- 发布时间
编译系统结构
- 作者

- Name
- wenjuGao
- github
- @Github
编译系统结构
1. 词法分析(lexical Analysis)
从左向右逐行扫描源程序的字符,识别出各个单词,确定单词类型,将识别的单词转换成统一的机内表示(词法单元token)
token<种别码,属性>
| 序号 | 单词类型 | 种别 | 种别码 |
|---|---|---|---|
| 1 | 关键字 | if、else、then... | 一词一码 |
| 2 | 标识符 | 变量名、数组名 | 多词一码 |
| 3 | 常量 | 整数、浮点数 | 一型一码 |
| 4 | 运算符 | +、- | 一词一码或一型一码 |
| 5 | 界限符 | ;{... | 一词一码 |
2. 语法分析(Syntax Analysis)
从词法分析器中输出的token序列中识别出各类短语,并构造语法分析树(parese tree)
语法分析树描述了句子的语法结构
3. 语义分析(Semantic Analysis)
收集标识符的属性信息:
- 种属(kind)
- 类型(type)
- 存储位置、长度
- 值
- 作用域
- 参数和返回值信息(参数个数、参数类型、参数传递方式、返回值类型、…)
语义检查:
- 变量或过程未经声明就使用
- 变量或过程名重复声明
- 运算分量类型不匹配
- 操作符与操作数之间的类型不匹配
- 数组下标不是整数
- 对非数组变量使用数组访问操作符
- 对非过程名使用过程调用操作符
- 过程调用的参数类型或数目不匹配
- 函数返回类型有误
4. 中间表达式形式
- 三地址码(Three-address Code)
- 三地址码由类似于汇编语言的指令序列组成,
- 每个指令最多有三个操作数(operand)
常见的三地址指令
| 序号 | 指令类型 | 指令形式 | 四元式形式 |
|---|---|---|---|
| 1 | 赋值指令 | x=y op z;x = op y | (op,y,z,x);(op,y,_,x) |
| 2 | 复制指令 | x=y | (=,y,_,x) |
| 3 | 条件跳转 | if x relop y goto n | (relop,x,y,n) |
| 4 | 非条件跳转 | goto n | (goto,_,_,n) |
| 5 | 参数传递 | param x | (param,_,_,x) |
| 6 | 过程调用 | call p,n | (call,p,n,_) |
| 7 | 过程返回 | return x | (return,_,_,x) |
| 8 | 数组引用 | x = y[i] | (=[],y,i,x) |
| 9 | 数组赋值 | x[i]=y | ([]=,y,x,i) |
| 10 | 地址及指针操作 | x= &y;x =*y;*x =y | (&,y,_,x); (=* ,y,_,x); ( *= ,y,_,x) |
地址可以具有如下形式之一
- 源程序中的名字
- 常量(constant)
- 编译器生成的临时变量(temporary)
将三地址指令表示为数据结构
四元式(quadruples)
- (op,y,z,x)
三元式(Triples)
间接三元式(Indirect triples)
语法结构树/语法树(Syntax Trees)
5. 目标代码生成器
- 目标代码生成以源程序的中间形式作为输入,并把它映射到目标语言
- 目标语言生成的一个重要任务是为程序中使用的变量合理分配寄存器