表达式的翻译

将表达式代码的SDD

表达式翻译成三地址代码的SDD

以上是将表达式翻译成三地址代码的SDD;

  • code 表示代码

  • addr 表示存放表达式结果的地址

  • new Temp() 生成临时变量

  • gen() 生成指令

为每一次计算引入一个临时变量存储计算结果。

增量式翻译方案:类似于边扫描边生成,gen 不仅构造新的三地址指令,还要将它添加到至今为止已生成的指令序列之后。不需要code 指令保存已有的代码,而是对gen 的连续调用生成一个指令序列。

增量式翻译方案,把code去除

数组元素的寻址

一维数组A[i] 的寻址:假设数组元素被存放在连续的存储空间中,元素从0到n-1编号,第i个元素的地址为:base + i*w

k维数组A[i1][i2]..[ik] 寻址:假设数组按行存放,首先存放A[0][i2]..[ik] ,然后存A[1][i2]...[ik] ...,那么A[i1][i2]...[ik] 的地址为:base + i1*w1 + i2*w2 + ... + ik*wk

其中base和w的值可以从符号表中找到:

数组引用的翻译

为数组引用生成代码要解决的主要问题是:数组引用的文法和地址计算相关联。假定数组编号从0开始,基于宽度来计算相对地址。

数组引用相关文法:非终结符号L生成数组名,加上一个下标表达式序列

LL[E]id[E]L\rightarrow L[E]|id [E]

非终结符号L的三个综合属性:

  • L.array是一个指向数组名字对应的符号表条目的指针L.array.base为该数组的基地址

  • L.addr指示一个临时变量,计算数组引用的偏移量

  • L.type是L生成的子数组的类型。对于任何(子)数组类型L.type,其宽度由L.type.width给出,L.type.elem给出其数组元素的类型

以上L的代码只计算了偏移量,数组元素的存放地址应该根据偏移量进一步计算,即L的数组基址加上偏移量,使用三地址指令x = a[i]

例子

Last updated