编译原理 龙书 第二版 第5、6章
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
11
(1)
12
(2)
op
Arg1
Arg2
0
+
b
c
1
minus
(0)
2
+
a
(1)
instruction
练习6.4.3:使用图6-22中的翻译方案,来翻译下列赋值语句
x=a[i][j]+b[i][j]
答:
假定数组a,b均为2*3规模的整型数组,且一个整数的宽度为4
x=a[i][j]+b[i]ቤተ መጻሕፍቲ ባይዱj]的注释语法分析树如下
C.false=NewLable();C.true=NewLable()
S1.next=S2.next=S.next
S.code=C.code
|| Lable(C.true) || S1.code
|| gen(‘goto’S.next)
|| Lable(C.false)|| S2.code
2) S->do S1 while (C)
L.syn=L’.syn
4)L’->BL1’
L1’.m=L’.m*L’.m;L1’.side=L’.side
L1’.inh=L’.inh*L’.side+B*L1’.m
L’.syn=L1’.syn
5)L’->ε
L’.syn=L’.inh
6)B->0
B.val=0
7)B->1
B.val=1
练习5.3.1:下面是涉及运算符+和整数或浮点运算分量的表达式文法。区分浮点数的方法是看它有无小数点。
If(E1.type==integerand T.type==float)then E1=intToFloat(E1)
Elseif(T.type==integer and E1.type==float) then T=intToFloat(T)
END
E.val = E1.val T.val +
2)E->T
a==b && (c==d || e==f)
答:
构造表达式的注释语法分析树如下
各产生式进行归约时产生的语义动作的相应指令如下
1)按B->E1 rel E2将a==b归约为B时语义动作相应的指令如下
100: if a==b goto–
101: goto–
2)产生式B->B1 && M B2中的标记非终结符号M记录了nextinstr的值,该值为102
E-〉E+T|T T-〉num.num|num
1)给出一个SDD来确定每个项T和表达式E的类型
2)扩展(1)中得到的SDD,使得它可以把表达式转换成为后缀表达式。使用一个单目运算符intToFloat把一个整数转换为相等的浮点数
答:
(1)
产生式
语义规则
1)E->E1+T
If E1.type ==T.type then E.type=E1.type
E.type=T.type; E.val=T.val
3)T->num
T.type=integer; T.val=num
4)T->num.num
T.type=float; T.val=num.num
练习5.4.4:为下面的产生式写出一个和例5.10类似的L属性SDD。这里的每个产生式表示一个常见的C语言中的那样的控制流结构。你可能需要生成一个三地址语句来跳转到某个标号L,此时你可以生成语句goto L
105: goto–
6)按照产生式B->B1 || M B2进行归约
7)按照产生式B->(B1)进行归约
8)按照产生式B->B1 && M B2进行归约
9)各子表达式的truelist和falselist在上图中已标出
答:
元文法消除左递归后可得到文法:
S->L.L|L L->BL’L’->BL’|ε B->0|1
使用继承属性L.side指明一个二进制位数在小数点的哪一边,2表示左边,1表示右边
使用继承属性m记录B的幂次
非终结符号L和L’具有继承属性inh、side、m和综合属性syn
产生式
语义规则
1)S->L
S.val=L.syn;
L.side=2;L.m=1;L.inh=0
2)S->L1.L2
L1.side=2;L2.side=1; L1.inh=0;L1.m=1;L2.m=1/2;L2.inh=0
S.val=L1.syn+L2.syn;
3)L->BL’
L’.m=L.m*L.m;L’.side=L.side
L’.inh=L.inh*L.side+B*L.m
Begin=NewLable()
C.false=NewLable();C.true=NewLable()
S1.next=begin
S.code=Lable(begin)||S1.code
|| Lable(C.true)
|| gen(‘goto’begin)
3)S->’{’L‘}’;
L -> L1S
L->ε
3)三元式序列
4)间接三元式序列
答:(1)抽象语法树
(2) 四元式序列
t1=b+c
t2=minus t1
t3=a+t2
op
Arg1
Arg2
result
0
+
b
c
T1
1
minus
T1
T2
2
+
a
T2
T3
(3)三元式序列
op
Arg1
Arg2
0
+
b
c
1
minus
(0)
2
+
a
(1)
(4)间接三元式序列
10
(0)
3)按B->E1 rel E2将c==d归约为B时语义动作相应的指令如下
102: if c==d goto–
103: goto–
4)产生式B->B1 || M B2中的标记非终结符号M记录了nextinstr的值,该值为104
5)按B->E1 rel E2将e==f归约为B时语义动作相应的指令如下
104: if e==f goto–
elseE.type=float
2)E->T
E.type=T.type
3)T->num
T.type=integer
4)T->num.num
T.type=float
(2)
产生式
语义规则
1)E->E1+T
If E1.type ==T.type then E.type=E1.type
Else begin
E.type=float
S.syn=L.syn;
S.inh=L1.syn; L.syn=S.syn
L.inh=L.syn
第六章
练习6.1.1:为下面的表达式构造DAG
((x+y)-((x+y)*(x-y)))+((x+y)*(x-y))
答:DAG如下
练习6.2.1:将算术表达式a+ - (b+c)翻译成
1)抽象语法树
2)四元式序列
x=a[i][j]+b[i][j]被翻译成的三地址代码如下如下
练习6.6.4:使用图6.6.5节中介绍的避免goto语句的翻译方案,来翻译下列表达式:
If (a==b && c==d || e==f) x==1;
答:
练习6.7.1:使用图6-43中的翻译方案翻译下列表达式。给出每个子表达式的truelist和falselist。你可以假设第一条被生成的指令地址是100.
第五章
练习5.1.1:
对于图5-1中的SDD,给出下列表达式对应的注释语法分析树:
1)(3+4)*(5+6)n
练习5.2.4:
这个文法生成了含“小数点”的二进制数:
S->L.L|L L->LB|B B->0|1
设计一个L属性的SDD来计算S.val,即输入串的十进制数值。比如,串101.101应该被翻译为十进制的5.625。提示:使用一个继承属性L.side来指明一个二进制位在小数点的哪一边。
1)S->if (C) S1 else S2
2)S->do S1 while (C)
3)S->’{’L‘}’; L -> LS|ε
请注意,列表中的任何语句都可以包含一条从它的内部跳转到下一个语句的跳转指令,因此简单地为各个语句按序生成代码是不够的。
答:
产生式
语义规则
1) S->if (C) S1 else S2
(1)
12
(2)
op
Arg1
Arg2
0
+
b
c
1
minus
(0)
2
+
a
(1)
instruction
练习6.4.3:使用图6-22中的翻译方案,来翻译下列赋值语句
x=a[i][j]+b[i][j]
答:
假定数组a,b均为2*3规模的整型数组,且一个整数的宽度为4
x=a[i][j]+b[i]ቤተ መጻሕፍቲ ባይዱj]的注释语法分析树如下
C.false=NewLable();C.true=NewLable()
S1.next=S2.next=S.next
S.code=C.code
|| Lable(C.true) || S1.code
|| gen(‘goto’S.next)
|| Lable(C.false)|| S2.code
2) S->do S1 while (C)
L.syn=L’.syn
4)L’->BL1’
L1’.m=L’.m*L’.m;L1’.side=L’.side
L1’.inh=L’.inh*L’.side+B*L1’.m
L’.syn=L1’.syn
5)L’->ε
L’.syn=L’.inh
6)B->0
B.val=0
7)B->1
B.val=1
练习5.3.1:下面是涉及运算符+和整数或浮点运算分量的表达式文法。区分浮点数的方法是看它有无小数点。
If(E1.type==integerand T.type==float)then E1=intToFloat(E1)
Elseif(T.type==integer and E1.type==float) then T=intToFloat(T)
END
E.val = E1.val T.val +
2)E->T
a==b && (c==d || e==f)
答:
构造表达式的注释语法分析树如下
各产生式进行归约时产生的语义动作的相应指令如下
1)按B->E1 rel E2将a==b归约为B时语义动作相应的指令如下
100: if a==b goto–
101: goto–
2)产生式B->B1 && M B2中的标记非终结符号M记录了nextinstr的值,该值为102
E-〉E+T|T T-〉num.num|num
1)给出一个SDD来确定每个项T和表达式E的类型
2)扩展(1)中得到的SDD,使得它可以把表达式转换成为后缀表达式。使用一个单目运算符intToFloat把一个整数转换为相等的浮点数
答:
(1)
产生式
语义规则
1)E->E1+T
If E1.type ==T.type then E.type=E1.type
E.type=T.type; E.val=T.val
3)T->num
T.type=integer; T.val=num
4)T->num.num
T.type=float; T.val=num.num
练习5.4.4:为下面的产生式写出一个和例5.10类似的L属性SDD。这里的每个产生式表示一个常见的C语言中的那样的控制流结构。你可能需要生成一个三地址语句来跳转到某个标号L,此时你可以生成语句goto L
105: goto–
6)按照产生式B->B1 || M B2进行归约
7)按照产生式B->(B1)进行归约
8)按照产生式B->B1 && M B2进行归约
9)各子表达式的truelist和falselist在上图中已标出
答:
元文法消除左递归后可得到文法:
S->L.L|L L->BL’L’->BL’|ε B->0|1
使用继承属性L.side指明一个二进制位数在小数点的哪一边,2表示左边,1表示右边
使用继承属性m记录B的幂次
非终结符号L和L’具有继承属性inh、side、m和综合属性syn
产生式
语义规则
1)S->L
S.val=L.syn;
L.side=2;L.m=1;L.inh=0
2)S->L1.L2
L1.side=2;L2.side=1; L1.inh=0;L1.m=1;L2.m=1/2;L2.inh=0
S.val=L1.syn+L2.syn;
3)L->BL’
L’.m=L.m*L.m;L’.side=L.side
L’.inh=L.inh*L.side+B*L.m
Begin=NewLable()
C.false=NewLable();C.true=NewLable()
S1.next=begin
S.code=Lable(begin)||S1.code
|| Lable(C.true)
|| gen(‘goto’begin)
3)S->’{’L‘}’;
L -> L1S
L->ε
3)三元式序列
4)间接三元式序列
答:(1)抽象语法树
(2) 四元式序列
t1=b+c
t2=minus t1
t3=a+t2
op
Arg1
Arg2
result
0
+
b
c
T1
1
minus
T1
T2
2
+
a
T2
T3
(3)三元式序列
op
Arg1
Arg2
0
+
b
c
1
minus
(0)
2
+
a
(1)
(4)间接三元式序列
10
(0)
3)按B->E1 rel E2将c==d归约为B时语义动作相应的指令如下
102: if c==d goto–
103: goto–
4)产生式B->B1 || M B2中的标记非终结符号M记录了nextinstr的值,该值为104
5)按B->E1 rel E2将e==f归约为B时语义动作相应的指令如下
104: if e==f goto–
elseE.type=float
2)E->T
E.type=T.type
3)T->num
T.type=integer
4)T->num.num
T.type=float
(2)
产生式
语义规则
1)E->E1+T
If E1.type ==T.type then E.type=E1.type
Else begin
E.type=float
S.syn=L.syn;
S.inh=L1.syn; L.syn=S.syn
L.inh=L.syn
第六章
练习6.1.1:为下面的表达式构造DAG
((x+y)-((x+y)*(x-y)))+((x+y)*(x-y))
答:DAG如下
练习6.2.1:将算术表达式a+ - (b+c)翻译成
1)抽象语法树
2)四元式序列
x=a[i][j]+b[i][j]被翻译成的三地址代码如下如下
练习6.6.4:使用图6.6.5节中介绍的避免goto语句的翻译方案,来翻译下列表达式:
If (a==b && c==d || e==f) x==1;
答:
练习6.7.1:使用图6-43中的翻译方案翻译下列表达式。给出每个子表达式的truelist和falselist。你可以假设第一条被生成的指令地址是100.
第五章
练习5.1.1:
对于图5-1中的SDD,给出下列表达式对应的注释语法分析树:
1)(3+4)*(5+6)n
练习5.2.4:
这个文法生成了含“小数点”的二进制数:
S->L.L|L L->LB|B B->0|1
设计一个L属性的SDD来计算S.val,即输入串的十进制数值。比如,串101.101应该被翻译为十进制的5.625。提示:使用一个继承属性L.side来指明一个二进制位在小数点的哪一边。
1)S->if (C) S1 else S2
2)S->do S1 while (C)
3)S->’{’L‘}’; L -> LS|ε
请注意,列表中的任何语句都可以包含一条从它的内部跳转到下一个语句的跳转指令,因此简单地为各个语句按序生成代码是不够的。
答:
产生式
语义规则
1) S->if (C) S1 else S2