文章目录
概览
编译:
将源语言翻译成目标语言的过程
分析源语言包括:
词法分析->语法分析->语义分析
编译器的结构:
词法分析(Lexical analysis)/ 扫描(Scanning)
从左到右扫描源程序字符(读入组成源程序的字符流),识别出各个单词(组成有意义的单词),确定单词类型,将识别出的单词转化为统一的机内表示——词法单元(token)
t o k e n token token: <token-name,attribute-value>
单词类型 | 种别 |
---|---|
关键字 | program、if、else、then…… |
标识符(identifier) | 变量名、数组名、记录名、过程名…… |
常量 | 整型、浮点型、字符型、布尔型…… |
运算符 | 算术(+ - * / ++ –)、关系(> < == != >= <=)、逻辑(& | ~) |
界限符 | ;、()、=、{}…… |
例子:
语法分析(Syntax analysis)/ 解析(Parsing)
从词法分析器输出的 t o k e n token token 序列,依据源程序的语法规则组成语法短语,表示成语法树(syntax tree)
例子:
语义分析(Semantic analysis)
使用语法树和符号表中的信息来检查源程序是否和语言定义的语义一致。
- 类型检查(type checking)
例如数组下标如果为浮点数,编译器必须报告错误。 - 自动类型转换(coercion)
例如运算符应用于一个整数和一个浮点数,编译器会把整数转换成浮点数。
中间代码(intermediate code)生成
在把一个源程序翻译成目标代码的过程中,一个编译器可能构造出一个或多个中间表示。
主要包括:
- 语法树(syntax tree)
- 三地址码(three-address code)
- 由类似于汇编语言的指令序列组成,每个指令最多三个操作数
这边简单了解一下,后面还会学习。。
表示:
- t1 = inttofloat(60)
- t2 = id3 * t1
- t3 = id2 + t2
- id1 = t3
代码优化(Code optimization)
机器无关的代码优化步骤试图改进中间代码,以便生成更好的目标代码。
代码生成
以源程序的中间表示形式作为输入,并把它映射到目标语言。
符号表(symbol table)管理
符号表数据结构为每个变量名字创建了一个记录条目。记录的字段就是名字的各个属性。
可以允许编译器迅速查找每个名字的记录,并向记录中快速存放和获取记录中的数据。
出错处理(Error handling)
- 检查错误
- 报告出错信息
- 排错
- 恢复编译工作
一些概念
- 遍(pass):对源程序(包括源程序中间形式)从头到尾扫描一次,并做有关加工处理,生成新的源程序中间形式或目标程序,称为一遍。
- 前端:与源程序有关的编译部分。
- 后端:与目标机有关的部分。
- 交叉编译:由于目标机指令系统和宿主机的指令系统不同,编译时将应用程序的源程序在宿主机上生成目标机代码,称为交叉编译。