绪论
绪论
回顾
- 预处理器(Preprocessor)
- 把存储在不同文件中的源程序聚合在一起
- 把称为宏的缩写语句转换为原始语句
- 编译器
- 汇编器(Assembler)
- 链接器(Linker)
- 将多个可重定位的机器代码文件(包括库文件)连接到一起
- 解决外部内存地址问题
- 加载器(Loader)
- 修改可重定位地址(绝对地址=起始地址+相对地址)
- 将修改后的指令和数据放到内存中适当的位置
编译器的结构
- 分析部分(前端)
- 词法分析器,语法分析器,语义分析器,中间代码生成器
- 机器无关代码优化器
- 综合部分(后端)
- 目标代码生成器,机器相关代码优化器
词法分析/扫描(scanning)
从左向右逐行扫描源程序的字符,识别出各个单词,确定单词的类型。将识别出的单词转换为统一的机内表示——词法单元形式
- token: <种别码, 属性码>
单词类型 | 种别 | 种别码 |
---|---|---|
关键字 | program, if, else, then … | 一词一码 |
标识符 | 变量名,数组名,记录名,过程名 | 多词一码 |
常量 | 整形,浮点型,字符型,布尔型… | 一型一码 |
运算符 | 算术,关系,逻辑 | 一词一码或一型一码 |
界限符 | ; ( ) = { } … | 一词一码 |
语法分析(parsing)
语法分析器(parser)从词法分析器输出的token序列中识别出各类短语,并构造语法分析树(parse tree)
语义分析
- 收集标识符的属性信息
- kind,type,存储位置,长度,值,作用域,参数和返回值信息
- 存储在符号表中,每个表项的NAME字段指向字符串表
- 语义检查
- 变量或过程未经声明就使用
- 变量或过程名重复声明
- 运算分量类型不匹配
- 操作符与操作数之间的类型不匹配
中间代码生成器
- 三地址码
- 每个指令最多有三个操作数
- 四元式
- 语法结构树/语法树(syntax trees)
目标代码生成器
以中间表示形式作为输入,并把它映射到目标语言
- 重要任务:为程序中使用的变量合理地分配寄存器
优化器
为改进代码所进行的等价程序变换,使其运行得更快一些、占用空间更少一些 优化方面
- 自动识别代码中的冗余部分,将其删除
- 将代价较高的运算替换成等价较低运算
- ……
编译程序的生成
编译器的自展
在同一机器上实现不同语言的编译器
编译器的移植(交叉编译)
将一台机器上运行的编译器进行处理,构造出在另一台机器上可以运行的编译器
This post is licensed under CC BY 4.0 by the author.