中间代码生成
来源:龙书(厚),南大课后作业
p232 6.1.1
为下面的表达式构造 DAG
((x+y)-((x+y)*(x-y)))+((x+y)*(x-y))
Answer
知识点
- 表达式的有向无环图 (Directed Acyclic Graph, DAG) 能够指出表达式中的公共子表达式,更简洁地表示表达式
p238 6.2.2
对下列赋值语句重复练习 6.2.1
- a = b[i] + c[j]
- a[i] = b*c - b*d
==在题目中添加条件:每个数组元素占 8个存储单元。 ==
(注: 只要求翻译成四元式序列和三元式序列)
Answer
-
a = b[i] + c[j]
-
四元式序列
o p op op a r g 1 arg_1 arg1 a r g 2 arg_2 arg2 r e s u l t result result 0 * i i i 8 8 8 t 1 t_1 t1 1 =[ ] b b b t 1 t_1 t1 t 2 t_2 t2 2 * j j j 8 8 8 t 3 t_3 t3 3 =[ ] c c c t 3 t_3 t3 t 4 t_4 t4 4 + t 3 t_3 t3 t 4 t_4 t4 t 5 t_5 t5 5 = t 5 t_5 t5 a a a -
三元式序列
o p op op a r g 1 arg_1 arg1 a r g 2 arg_2 arg2 0 * i i i 8 1 =[ ] b b b (0) 2 * j j j 8 3 =[ ] c c c (2) 4 + (1) (3) 5 = a a a (4)
-
-
a[i] = b*c - b*d
-
四元式序列
o p op op a r g 1 arg_1 arg1 a r g 2 arg_2 arg2 r e s u l t result result 0 * b b b c c c t ! t_! t! 1 * b b b d d d t 2 t_2 t2 2 - t 1 t_1 t1 t 2 t_2 t2 t 3 t_3 t3 3 * i i i 8 8 8 t 4 t_4 t4 4 + a a a t 4 t_4 t4 t 5 t_5 t5 5 *= t 3 t_3 t3 t 5 t_5 t5 -
三元式序列
o p op op a r g 1 arg_1 arg1 a r g 2 arg_2 arg2 0 * b b b c c c 1 * b b b d d d 2 - (0) (1) 3 * i i i 8 4 + a a a (3) 5 *= (4) (2)
-
知识点
- 三地址指令的四元式与三元式表示
p247 6.4.3
使用图 6-22 的翻译方案来翻译下列赋值语句:
x = a[ i ] [ j ] + b[ i ] [ j ]
在题目中添加条件说明:
1) a 表示一个2*3 的整型数组,b 表示一个2*4 的整型数组;
2) 一个整数的宽度为4 个字节。
Answer
x = a[ i ] [ j ] + b[ i ] [ j ] 的注释语法分析树如下
对应翻译出的三地址代码:
t1=i*12
t2=j*4
t3=t1+t2
t4=a[t3]
t5=i*16
t6=j*4
t7=t5+t6
t8=b[t7]
t9=t4+t8
x=t9
知识点
- 赋值语句的翻译
- 数组引用的翻译
p248 6.4.8
一个按行存放的实数型数组 A[i, j, k] 的下标 i 的范围为 1~4,下标 j 的范围为 0~4,且下标 k 的范围为 5~10。每个实数占 8 个字节。假设数组 A 从 0 字节开始存放,计算下列元素的位置:
- A[3, 4, 5]
- A[1, 2, 7]
- A[4, 3, 9]
Answer
计算公式:0+((i-1) * 5 * 6 + j * 6 + (k-5)) * 8
1. ((3-1) * 5 * 6 + 4 * 6 + (5-5)) * 8 = 672
2. ((1-1) * 5 * 6 + 2 * 6 + (7-5)) * 8 = 112
3. ((4-1) * 5 * 6 + 3 * 6 + (9-5)) * 8 = 896
知识点
- 数组下标计算
p263 6.6.1
在图 6-36 的语法制导定义中添加处理下列控制流构造的规则:
- 一个 repeat 语句:repeat S while B
- !一个 for 循环语句:for (S1; B; S2) S3
Answer
- 一个 repeat 语句:repeat S while B
语义规则:
s1.next=newlabel();
B.true=newlabel();
B.false=S.next;
S.code=label(B.true)||S1.code||label(S1.next||B.code||gen('goto' B.true)
- !一个 for 循环语句:for (S1; B; S2) S3
语义规则:
S1.next=newlabel();
B.true=newlabel();
B.false=S.next;
S2.next=S1.next;
S3.next=newlabel();
S.code=S1.code||label(S1.next)||B.code||label(B.true)||S3.code
||label(S3.next)||S2.code||gen('goto' S1.next)
知识点
- 控制流语句的翻译
- 龙书P244
p268 6.7.1
使用图 6-43 中的翻译方案翻译下列表达式。给出每个子表达式的 truelist 和 falselist。你可以假设第一条被生成的指令的地址是 100.
- a==b && (c==d || e==f)
- (a==b || c==d) || e==f
Answer
- a==b && (c==d || e==f)
注释语法分析树:
生成的代码:
2. (a==b || c==d) || e==f
注释语法分析树:
生成的代码:
知识点
- 布尔表达式的回填