第六章 中间代码生成
类型表达式(Type Expression)
- 基本类型是类型表达式
- 可以为类型表达式命名,类型名也是类型表达式
- 将类型构造符(type constructor)作用于类型表达式可以构成新的类型表达式
- 数组构造符 array
- 若T是类型表达式,则
是类型表达式(I是一个整数)
- 若T是类型表达式,则
- 指针构造符 pointer
- 若T是类型表达式,则 pointer(T) 是类型表达式,它表示一个指针类型
- 笛卡尔乘积构造符
- 若
和
是类型表达式,则笛卡尔乘积
是类型表达式
- 若
- 函数构造符
- 若
和R是类型表达式,则
是类型表达式
- 若
- 记录构造符 record
- 若有标识符
与类型表达式
,则
是一个 类型表达式
- 若有标识符
- 数组构造符 array
- 例子:
声明语句的翻译
局部变量的存储分配
- 对于声明语句,语义分析的主要任务就是收集标识符的类型等属性信息,并为每一个名字分配一个相对地址
- 从类型表达式可以知道该类型在运行时所需的存储单元数量称为类型的宽度
- 在编译时刻,可以使用类型的宽度为每一个名字分配一个相对地址
- 名字的类型和相对地址信息保存在相应的符号表记录中
简单赋值语句的翻译
赋值语句的任务
- 赋值语句的基本文法
- 赋值语句翻译的主要任务
- 生成对表达式求值的三地址码
- 增量翻译
- 在增量方法中,gen()不仅要 构造出一个新的三地址指令,还要将它添加到至今为止已生成的指令序列之后
- 在增量方法中,gen()不仅要 构造出一个新的三地址指令,还要将它添加到至今为止已生成的指令序列之后
- 生成对表达式求值的三地址码
数组引用的翻译
- 对之前的赋值语句的基本文法进行扩展
- 将数组引用翻译成三地址码时要解决的主要问题是确定数组元素的存放地址,也就是数组元素的寻址
数组元素的寻址
- 一维数组
- 假设每个数组元素的宽度是 w, 则数组元素a[i]的相对地址为:
- base + i * w (其中,base是数组的基地址,i * w 是偏移地址)
- 假设每个数组元素的宽度是 w, 则数组元素a[i]的相对地址为:
- 二维数组
- 假设一行的宽度是
,同一行中每个数组元素的宽度是
,则数组元素
的相对地址是:
- 假设一行的宽度是
- k维数组
带有数组引用的赋值语句的翻译
数组引用的SDT
L的综合属性
- L.type:L生成的数组元素的类型
- L.offset:指示一个临时变量,该临时变量用于累加公式中的 偏移地址的每一项,从而计算数组引用的偏移量
控制流语及其SDT
控制流语句的基本文法
控制流语句的代码结构
- 继承属性
- S.next : 是一个地址,该地址中存放了紧跟在S代码之后的指令(S的后继指令)的标号
- B.true : 是一个地址,该地址中存放了当B为真时控制流转向的指令的标号
- B.false : 是一个地址,该地址中存放了当B为假时控制流转向的指令的标号
- 用指令的标号标识一条三地址指令