当前位置:文档之家› 编译原理(龙书)习题(5,6,7,8)章

编译原理(龙书)习题(5,6,7,8)章


8.6.1 为下面的每个C语言赋值语句生成三地址代码 LD R1 , b 1)x = a + b * c; LD R2 , c MUL R1 , R1 , R2 t1 = b * c LD R3 , a ADD R1 , R1 , R3 t2 = a + t1 ST x , R1 x = t2 3) x = a[i] + 1 t1 = a[i] t2 = t1 + 1 x = t2
D1 .b
D1.val;
D.b D1.b 1}
第6章 中间代码生成
6.1.1 为下面的表达式构造DAG ((x+y)-((x+y)*(x-y)))+((x+y)*(x-y))
6.2.1 将算术表达式 a+-(b+c) 翻译成
1)抽象语法树 2)四元式序列 3)三元式序列 4)间接三元式序列
LD R4 , b(R3) ST y , R4 LD R5 , x LD R6 , y MUL R5 , R5 , R6 ST z , R5
8.2.4 假设x,y和z存放在内存位置中,为下面的语句序列生成 代码: LD R1 , x if x < y goto L1 LD R2 , y z=0 SUB R1 , R1 , R2 goto L2 BLTZ R1 , L1 L1:z = 1 LD R3 , 0 ST z , R3 JMP L2 L1:LD R4 , 1 ST z , R4
6.4.3 使用使用图6-22所示的翻译方案来翻译下 列赋值语句: 2) x = a[i][j] + b[i][j] 假设w1为数组a的第一维的宽度,w2为数组b 的第 一维的宽度,整数的宽度为w。 t1 = i * w1; t2 = j * w; t3 = t1 + t2; t4 = a[t3]; t6 = j * w; t7 = t5 + t6; t8 = b[t7]; t9 = t4 + t8;
DAG
优化后的三地址语句序列: t1 = a + c y = t1 + e t3 = y + b t4 = t3 + d x = t4 + f
优化后的目标代码序列: LD R1 , a LD R2 , c ADD R1 , R1 , R2 LD R2 , e ADD R1 , R1 , R2 ST y , R1 LD R2 , b ADD R1 , R1 , R2 LD R2 , d ADD R1 , R1 , R2 LD R2 , f ADD R1 , R1 , R2 ST x , R1
MUL R3 , R3 , 4 ADD R3 , R3 , SP LD R4 , b(R3) ST y(SP) , R4 LD R5 , x(SP) LD R6 , y(SP) MUL R5 , R5 , R6 ST z(SP) ,R5
8.5.1 为下面的基本块构造DAG。 d = b*c e = a+b b = b*c a = e-d
为了求小数部分的值,引入L的综合属性b记录2的 L 的位数次幂值(2 length of L) S L1.L2 S.val = L1.val +L2.val / L2.b; SL S.val = L.val; L L1 B L.val = L1.val *2 + B.val; L.b = L1.b*2; LB L.val = B.val; L.b = 2; B0 B.val = 0; B1 B.val = 1;
(2)设code 为综合属性,代表各非终结符 的代码属性 type为综合属性,代表各非终结符的类型属 性 inttoreal把整型值转换为相等的实型值 vtochar将数值转换为字符串
5.3.3 给出一个SDD对x*(3*x+x*x)这样的表达式求 微分。表达式中涉及运算符+和*,变量x和常 量。假设不进行任何简化,也就是说,比如 3*x将被翻译为3*1+0*x。 exp 为原表达式的字符串,s 为求导后的字符串。 || 为串联接符。
6.7.7 使用图6-37中的翻译方案翻译下列表达 式。给出每个子表达式的truelist和falselist。 你可以假设第一条被生成的指令的地址是 100。
1)a==b&&(c==d||e==f)
100: if a==b goto 102 101: goto __ 102: if c==d goto __ 103: goto 104 104: if e==f goto __ 105: goto __
2)假设x和y都在基本块的出口处活跃,利用加法的结合律和交 换律来修改这个基本块,使得指令个数最少。 把原始的赋值语句进行调整: x = a+c+e+b+d+f y = a+c+e 对应的三地址语句序列: t1 = a + c t2 = t1 + e t3 = t2 + b t4 = t3 + d t5 = t4 + f x = t5 t6 = a + c t7 = t6 + e y = t7
第5章 语法制导的翻译
BCD 5.2.3 假设我们有一个产生式 A 。 A,B,C,D这四个非终 结符号都有两个属性:s是一个综合属性,而i是一个继承属 性。对于下面的每组规则,指出(i)这些规则是否满足S属性 定义的要求。(ii)这些规则是否满足L属性定义的要求。(iii) 是否存在和这些规则一致的求值过程? 1)A.s = B.i + C.s 不满足S属性定义,满足L属性定义 2)A.s = B.i + C.s 和 D.i = A.i + B.s 不满足S属性定义,满足L属性定义 3)A.s = B.s + D.s 满足S属性定义,满足L属性定义 4)A.s=D.i,B.i=A.s+C.s,C.i=B.s和D.i=B.i+C.i 不满足S属性定义,不满足L属性定义
5.2.4 这个文法生成了含“小数点”的二进制:
S L.L | L L LB | B B 0 |1
设计一个L属性的SDD来计算S.val,即输入串的十进制数值。 比如,串101.11应该被翻译为十进制数5.635。提示:使 用一个继承属性L.side来指明一个二进制位在小数点的哪 一边。
8.3.3 假设使用栈式分配,且假设a和b都是元素大小为4字节 的数组,为下面的三地址语句生成代码。 LD R1 , i 2)三个语句序列 MUL R1 , R1 , 4 ADD R1 , R1 , SP x = a[i] LD R2 , a(R1) y = b[i] ST x(SP) , R2 LD R3 , i z = x*y
5.3.1 下面是涉及运ห้องสมุดไป่ตู้符+和整数或浮点运算分量的表达式的 文法。区分浮点数的方法是看它有无小数点。
E E T |T T num.num | num
1)给出一个SDD来确定每个项T和表达式E的类型。 2)扩展(1)中得到的SDD,使得它可以把表达式转换成为后缀 表达式。使用一个单目运算符intToFloat把一个整数转换为 相等的浮点数。
非终结符D的综合属性b表示二进制数的位数, val表 示对应的十进制数的数值。消除左递归后如下: D .b
B 1D {B.val 1 2 D.val} D 0 D1 {D.val D1.val; D.b D1.b 1} | 1D1 {D.val 1 2 | {D.val 0; D.b 0}
1)抽象语法树:
2)四元式序列:
3)三元式序列:
4)间接三元式序列:
6.4.1 向图6-19的翻译方案中加入对应于下列产生式的规则: 1) E E1 * E2 2) E E1 (单目加)
6.4.2 使用图6-20中的增量式翻译方案重复练习6.4.1
在增量方式中,gen不仅要构造出一个新的三地址指令,还 要将它添加到至今为止已生成的指令序列之后。
S-->for ( S1; B; S2 ) S3 S1.next=newlabel() B.true=newlabel() begin=newlabel() B.fale=S.next S2.next =S1.next S3.next=begin S.code=S1.code||label(S1.next)|| B.code||label(begin)|| S2.code|| gen('goto' S1.next)|| label(B.true)||S3.code|| gen('goto' begin)
第7章 运行时环境
7.2.3 图7-9中是递归计算Fiabonacci数列的C语言代码。假设f 的活动记录按顺序包含下列元素:(返回值,参数n,局 部变量s,局部变量t)。通常在活动记录中还会有其他元 素。下面的问题假设初始调用是f(5)。
int f(int n) { int t,s; if (n<2) return 1; s = f(n-1); t = f(n-2); return s+t; } 图7-9
函数返回值为:12 此时a的值为:6
第8章 代码生成
8.2.1 假设所有的变量都存放在内存中,为下 面的三地址语句生成代码: 1) x = 1 LD R1 , 1 ST x , R1
3) x = a + 1 LD R1 , a ADD R1 , R1 , 1
8.2.2 假设a和b是元素为4字节值的数组,为下面的三地址语 句序列生成代码。 LD R1 , i 2)三个语句序列 MUL R1 , R1 , 4 x = a[i] LD R2 , a(R1) ST x , R2 y = b[i] LD R3 , i z=x*y MUL R3 , R3 ,4
1)只有a在基本块 的出口处活跃: d=b*c e=a+b a=e-d
相关主题