编译器架构Compiler Architecture(下)
编译器架构Compiler Architecture(下)
Combining Scanning and Parsing
实际上没有必要将扫描(词法分析/标记化)与解析(语法分析/树生成)分开。基于PEGs的系统,比如Ohm,实际上是无扫描的:它们以一种预测的方式执行解析,将词汇和语法规则混合在一起。(但是,像Ohm这样的系统需要一个预解析阶段来处理缩进和凹陷。)
当使用无扫描系统时,语言设计者和编译器编写者仍然会考虑符号和短语,但不必担心像所谓的最大Munch原则这样的复杂规则。Lookahead捕获您需要的任何类型的标记化方案。此外,无扫描解析的预测性意味着我们不必确定*是一元运算符指针解引用令牌,还是二进制乘法运算符令牌或星形令牌。在进行预测性分析时,我们总是有上下文。
Semantic Analysis
在语义分析过程中,我们必须检查合法性规则,同时,我们将语法树的片段(通过解析标识符引用、为隐式强制插入强制转换操作等)捆绑起来,形成一个语义图。
继续上面的例子:


显然,每种语言的合法性规则是不同的。您可能会在类似Java的语言中看到的合法性规则示例包括:
一个范围内的变量的多个声明
在变量声明之前引用它
引用没有声明的标识符
违反访问(公共、私有、受保护等)规则
方法调用中的参数太多
方法调用中没有足够的参数
类型不匹配(有很多这样的情况)
练习:列举以上每一个例子。
在此阶段发生的错误称为静态语义错误。
练习:Pascal语言在表达式方面有一种不同寻常的语法:它赋予and运算符(需要布尔操作数)比关系运算符更高的优先级!说明这意味着表达式x-4<=5和2<y是静态语义错误。
中间代码生成Intermediate Code Generation
中间代码生成器生成一个流图,由分组到基本块中的元组组成。对于上面的例子,我们可以看到:

可以在其他地方阅读更多关于中间表示的内容。
Machine Independent Code Improvement
对语义图或中间代码进行的代码改进称为与机器无关的代码优化。在实践中,有无数已知的优化(er,改进),但没有一个真正适用于我们的运行示例。
Code Generation
代码生成产生实际的目标代码,或者类似的代码。这是我在使用面向x86-64的gcc 6.3进行组装时得到的结果,没有任何优化:

以下是ARM的代码,使用gcc 5.4,无需优化:

MIPS代码,gcc 5.4也未优化:


Machine Dependent Code Improvement
通常编译的最后阶段是清理和改进目标代码。对于上面的例子,我在将优化级别设置为-O3时得到了如下结论:

Optimized ARM code:

Optimized MIPS code:

编译器架构Compiler Architecture(下)的更多相关文章
- 编译器架构Compiler Architecture(上)
编译器架构Compiler Architecture(上) 编译器是程序,通常是非常大的程序.它们几乎都有一个基于翻译分析综合模型的结构. CONTENTS Overview • Compiler C ...
- NVIDIA Turing Architecture架构设计(下)
NVIDIA Turing Architecture架构设计(下) GDDR6 内存子系统 随着显示分辨率不断提高,着色器功能和渲染技术变得更加复杂,内存带宽和大小在 GPU 性能中扮演着更大的角色. ...
- 微内核架构(Microkernel Architecture)
微内核架构(Microkernel Architecture) 微内核架构有时也被成为插件架构模式(plug-in architecture pattern),通常用于实现基于产品的应用,如Eclip ...
- 事件驱动架构 (Event-Driven Architecture,EDA) 简介
EDA 是一种侧重于以生成/消费为基础的异步通信的架构模式.这主要对照于传统的基于线程的同步系统. EDA 是一种以事件 (event)为核心,提供事件产生,路由,消费已经结果回调等机制的架构模式. ...
- TOGAF架构内容框架之架构制品(下)
TOGAF架构内容框架之架构制品(下) 4.2.31 数据生命周期图(Data Lifecycle Diagram) 数据生命周期图是在业务流程的约束之下对业务数据在其整个生命周期(从概念阶段到最终退 ...
- 朱晔的互联网架构实践心得S1E8:三十种架构设计模式(下)
朱晔的互联网架构实践心得S1E8:三十种架构设计模式(下) [下载本文PDF进行阅读] 接上文,继续剩下的15个模式. 数据管理模式 16.分片模式:将数据存储区划分为一组水平分区或分片 一直有一个说 ...
- 大数据分析的下一代架构--IOTA架构设计实践[下]
大数据分析的下一代架构--IOTA架构设计实践[下] 原创置顶 代立冬 发布于2018-12-31 20:59:53 阅读数 2151 收藏 展开 IOTA架构提出背景 大数据3.0时代以前,Lam ...
- LLVM编译器架构
LLVM编译器架构 LLVM概述 LLVM项目是模块化和可重用的编译器及工具链技术的集合.尽管名称如此,LLVM与传统虚拟机关系不大.名称" LLVM"本身不是缩写.它是项目的全名 ...
- 架构(Architecture)和框架(Framework)杂谈
1. 架构和框架的设计层次不同 类似于硬件设计,软件设计也分为不同的层次.典型的软件设计层次如下图: 在这个图中我们可以看到,Framework处于Micro-archite ...
随机推荐
- hook Android系统调用的乐趣和好处
翻译:myswsun 0x00 前言 Android的内核是逆向工程师的好伙伴.虽然常规的Android应用被限制和沙盒化,逆向工程师可以按自己希望自定义和改变操作系统和内核中行为.这给了你不可多得的 ...
- 2021ArchSummit全球架构师峰会上,大家在聊些什么
大会PPT公开下载链接:https://ppt.infoq.cn/list/assh2021 大会主要情况介绍 2021 ArchSummit全球架构师峰会是该大会正式成立的第十年,是极客邦科技旗下I ...
- 日期格式化时注解@DateTimeFormat无效的问题分析
作者:汤圆 个人博客:javalover.cc 背景 有时候我们在写接口时,需要把前台传来的日期String类型转为Date类型 这时我们可能会用到@DateTimeFormat注解 在请求数据为非J ...
- 拿到列表的长度len(列表名)
拿到列表的长度len(列表名),即元素个数 列表要放在括号里面
- Spring 注解动态数据源设计实践
Spring 动态数据源 动态数据源是什么?解决了什么问题? 在实际的开发中,同一个项目中使用多个数据源是很常见的场景.比如,一个读写分离的项目存在主数据源与读数据源. 所谓动态数据源,就是通过Spr ...
- [Python] 可变/不可变类型 & 参数传递
与c/c++不同,Python/Java中的变量都是引用类型,没有值类型 Python赋值语句由三部分构成,例如: int a = 1 类型 标识 值 标识(identity):用于唯一标识 ...
- 036.Python的TCP语法
TCP语法 1 建立一个socket对象 import socket sk = socket.socket() print (sk) 执行 [root@node10 python]# python3 ...
- docker命令补全
安装docker自带包: source /usr/share/bash-completion/completions/docker 缺少下面的包,TAB会报错 yum install -y bash- ...
- MyBatis 高级查询之一对一查询(九)
高级查询之一对一查询 查询条件:根据游戏角色ID,查询账号信息 我们在之前创建的映射器接口 GameMapper.java 中添加接口方法,如下: /** * 根据角色ID查询账号信息 * @para ...
- http keep-alive 的一些理解
在日常的工作中涉及到了关于检测用户是否在线的功能需求,在方案设计过程中考虑过使用http-keepalive的方式,由于我们获取到的keepalive是经过nginx转发的keep-alive,所以最 ...