语义分析和中间代码产生
中间语言
源语言程序 ⇒Compiler Front End 中间语言程序 ⇒Compiler Back End 目标语言程序
常用的中间语言
- 后缀式,逆波兰表示
- 图表示:DAG、抽象语法树
- 三地址代码
- 三元式
- 四元式
- 间接三元式
后缀式
无循环有向图
三地址代码
三地址代码
x:=y op z
三地址代码可以看成是抽象语法树或DAG的一种线性表示
赋值语句的翻译
直接赋值语句
i = 0;
翻译后:
i = 0
自己对自己赋值
i = i + 1;
翻译后:
t1 = i + 1
i = t1
布尔表达式的翻译
控制语句的翻译
一个if套一个条件
原语句
if(expr1) {
statement1;
}
statement2;
翻译:
if (expr1) goto L1
goto L2
L1: statement1
L2: statement2
if-else
原语句
if(expr1) {
statement1;
} else {
statement2;
}
statement3;
翻译:
if(expr1) goto L1
goto L2
L1: statement1
goto L3
L2: statement2
L3: statement3
while套两个条件
原语句
while(expr1 && expr2) {
statement1;
}
statement2;
翻译:
L0: if(expr1) goto L2
L1: goto L4
L2: if(expr2) goto L3
goto L1
L3: statement1
goto L0
L4: statement2
过程调用的处理
数组型
a[i1][i2]
翻译后:
首先我们假设:
- a数组的起始位置是addrA
- 每个数组元素所占大小为w
- 数组是从 li1,li2 开始计数的,到 ui1,ui2 为止,我们私下将 ui2−li2 算好,记做 n2
t1 = l1 * n2
t2 = t1 + l2
t3 = t2 * w
t4 = addrA - t3
########以上部分与下标均无关###############
t5 = i1 * n2
t6 = t5 + i2
t7 = t6 * w
t8 = t4[t7]
具体推导:
Addr(A[i1, i2])
=addrA+((i1-low1)*n2+i2-low2)*w
=(i1*n2+i2)*w+addrA-(low1*n2+low2)*w
=addrA-(low1*n2+low2)*w+(i1*n2+i2)
Where n2=upper2-low2+1
此时对着最后的式子写就好了
拉链-回填
只要会翻译,回填就是换个标号的问题