编译原理-中间代码生成 课后习题+笔记
中间代码生成来源:龙书(厚),南大课后作业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.1a = b[i] + c[j]a[i]
中间代码生成
来源:龙书(厚),南大课后作业
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]
-
四元式序列
opopop arg1arg_1arg1 arg2arg_2arg2 resultresultresult 0 * iii 888 t1t_1t1 1 =[ ] bbb t1t_1t1 t2t_2t2 2 * jjj 888 t3t_3t3 3 =[ ] ccc t3t_3t3 t4t_4t4 4 + t3t_3t3 t4t_4t4 t5t_5t5 5 = t5t_5t5 aaa -
三元式序列
opopop arg1arg_1arg1 arg2arg_2arg2 0 * iii 8 1 =[ ] bbb (0) 2 * jjj 8 3 =[ ] ccc (2) 4 + (1) (3) 5 = aaa (4)
-
-
a[i] = b*c - b*d
-
四元式序列
opopop arg1arg_1arg1 arg2arg_2arg2 resultresultresult 0 * bbb ccc t!t_!t! 1 * bbb ddd t2t_2t2 2 - t1t_1t1 t2t_2t2 t3t_3t3 3 * iii 888 t4t_4t4 4 + aaa t4t_4t4 t5t_5t5 5 *= t3t_3t3 t5t_5t5 -
三元式序列
opopop arg1arg_1arg1 arg2arg_2arg2 0 * bbb ccc 1 * bbb ddd 2 - (0) (1) 3 * iii 8 4 + aaa (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
注释语法分析树:
生成的代码:
知识点
- 布尔表达式的回填



更多推荐


所有评论(0)