第七章 中间代码
7.1 中间语言
语法树
后缀式
三地址代码表示
7.1.1 图表示法
语法树,有向非循环图和后缀式表示源程序的自然层次结构,例如:
a:=b * - c+b * -c
赋值语句:
中 缀式: a:=b*-c+b*-c
后缀式:
a b c - * b c - * + =
7.1.2 三地址代码
一般形式 x:=y op z
(1)赋值语句 x:=y op z,op为二目算术算符或逻辑算符;
(2)赋值语句 x:=op y ,op为一目算符,如一目减uminus、逻辑非not、移位算符及转换算符;
(3)无条件转移语句goto L;
(4)条件转移语句 if x relop y goto L,关系运算符号relop(< ,=,>= 等等);
(5)复制语句 x:=y;
(6)过程调用语句 param x 和 call p, n ;
过程返回语句 return y;
(7)索引赋值 x:=y[i] 及 x[i] :=y ;
(8)地址和指针赋值 x=&y,x=* y
和 * x=y。
在设计中间代码形式时,选择多少种算
符 需 要 trade off .
7.1.4 语法制导翻译生成三地址代码
几个用到的量:
(1)E.place表示存放E值的名字。
(2)E.code表示对E求值的三地址语句序列。
(3) newtemp是个函数,对它的调用将产生 一个新的临时变量。
三地址语句序列是语法树的线性表示,用临时变量代替语法树中的结点。
实际实现中,三地址语句序列往往是被存放到一个输出文件中,而不是将三地址语句序列置入code属性之中
7.1.5 三地址代码的具体实现
1.四元式 op, arg1, arg2, result
2.三元式 op, arg1, arg2
3.间接三元式 间接码表+三元式表
四元式需要利用较多的临时单元,四元式之 间 的联系通过临时变量实现。
中间代码优化处理时,四元式比三元式方便的多,间接三元式与四元式同样方便,两种实现方式需要的存储空间大体相同。
对于语句a:=b*-c+b*-c 的三种表示方法
三地址语句的四元式表示
(- , c , , t1)
(* , b , t1 , t2)
(- , c , , t3)
(* , b , t1, t4)
(+ ,t2 , t4 , t5)
(= , t5 , ,a)
三地址语句的三元式表示
三元式中使用指向三元式语句的指针。
三地址语句的间接三元式表示
语句的移动仅改变左边的语句表
7.2 常用语句的翻译
7.2.1 说明语句
说明语句的翻译:对每个局部名字在符号表中建立相应的表项,填写有关的信息。如类型、嵌套深度、相对地址、内情向量等。
相对地址:相对静态数据区基质,或在活动中局部数据区基质的一个偏移值。
一、 过程中的说明语句
一个过程中的所有说明语句作为一个类集处理。用一个全程变量offset来记录下一个数据在符号表中的相对地址。
7.2.2 赋值语句
赋值语句的翻译:
表达式的成分可以是整型量、实型量、数组 元素和记录
一、 符号表中的名字
名字可以理解为指向符号表中相应该名字表项的指针
如何根据名字查找符号表的表项?
过程lookup(id.name)检查是否在符号表中存在相应此名字的表项。
二、简单算术表达式及赋值语句
lookup(id.name)= id.entry
nil
emit 它将生成的三地址代码送到输出文件上。例:
emit(E.place‘:=’E1.place‘+’E2.place) 或
emit(= , E1.place,E2.place, E.place)
产生赋值语句三地址代码的翻译模式