编译TopDowntBottomUp习题解答.docx
- 文档编号:26783405
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:16
- 大小:166.94KB
编译TopDowntBottomUp习题解答.docx
《编译TopDowntBottomUp习题解答.docx》由会员分享,可在线阅读,更多相关《编译TopDowntBottomUp习题解答.docx(16页珍藏版)》请在冰豆网上搜索。
编译TopDowntBottomUp习题解答
1、已知文法G(S):
SfaS|bS|a
(1)构造该文法的LR(O)项目集规范族
(2)构造识别该文法所产生的活前缀的DFA。
(3)构造其SLR分析表,并判断该文法是否是SLR
(1)文法。
解题思路
构造LR(O)项目集规范族,有两种方法:
一种是利用有限自动机来构造,另一种是利用函数CLOSURE和GO来构造。
本题采取第2种方法,通过计算函数CLOSURE和GO得到文法的LR(O)项目集规范族,而GO函数则把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA。
解答
(1)将文法G(S)拓广为G(S'):
(O)S'fS
(1)SfaS
(2)SfbS
(3)Sfa
构造该文法的LR(0)项目集规范族:
lo=CLOSURE({SS})={S厶S,S^aS,S^bS,S-a}
Ii=GO(Io,a)=CLOSURE({S-aS,S-a})={S-aS,S-a•,S—aS,
SfbS,Sf}a
I2=GO(Io,b)=CLOSURE({S-bS})={S-bS,S-aSS,-bS,S-}a
I3=GO(Io,S)=CLOSURE({S'-S})={S'}-S
GO(I1,a)=CLOSURE({S-aS,S-a})=I1
GO(I2,b)=CLOSURE({S-bS})=I2
I4=GO(I1,S)=CLOSURE({S-aS})={S-aS}
GO(I2,a)=CLOSURE({S-aS,S-a})=I1
GO(I2,b)=CLOSURE({S-bS})=I2
I5=GO(I2,S)=CLOSURE({S-bS})={S-bS}
所以,项目集Io,|1,|2,|3,|4和|5构成了该文法的LR(O)项目集规范族。
(2)我们用GO函数把LR(o)项目集规范族连成一个识别该文法所产生的活前缀的DFA如图4.1所示。
(3)构造其SLR分析表。
表4.1SLR分析表
ACTION
GOTO
状态
a
b
#
S
0
S1
S2
3
1
S1
S2
r3
4
2
S1
S2
5
3
acc
4
r1
5
r2
注意到状态Ii存在“移进-归纳”冲突,计算S的FOLLOW集合:
FOLLOW(S)={#}
可以采用SLR冲突消解法,得到表4.1所列的SLR分析表。
从分析表可以看出,表中没有冲突项,所以该文法是SLR
(1)文法。
2、证明AdBd是文法G(S)的活前缀。
说明活前缀在LR分析中的作用。
给出串dbdb#的LR分析过程。
G(S):
(1)S—AdB
(2)A—a(3)A
⑷B—b(5)B—BdbQB—£
解题思路
所谓活前缀是指规范句型的一个前缀,这种前缀不句柄之后的任何符号。
根据此定义,直接证明AdBd是文法G(S)的活前缀。
解答
存在下面的规范推导:
Sl》AdB・〉AdBdb
可见AdBdb是文法G的规范句型,AdBd是该规范句型的前缀。
另外,在该规范句型中Bdb是句柄,前缀是AdBd不含句柄Bdb之后的任何符号,所以AdBd是文法G(S)的活前缀。
在LR分析工作过程中的任何时候,栈里的方法符号(自栈底而上)X1X2…Xm应该构成活前缀,把输入串的剩余部分配上之后即应成为规范句型(如果整个输入串确实构成一个句
子)。
因此,只要输入串的已扫描部分保持可归约成一个活前缀,那就意味着所扫描过的部分没有错误。
构造文法G的LR分析表4.2所列。
表4.2LR分析表
ACTION
GOTO
a
d
b
#
S
A
B
0
s3
r3
1
2
1
acc
2
s4
3
r2
4
r6
s5
r6
6
5
r4
r4
6
s7
r1
7
s8
8
r5
r5
串dbdb#的LR分析过程如下:
步骤
状态
符号
输入串
0
0
#
dbdb#
1
02
#A
dbdb#
2
024
#Ad
bdb#
3
0245
#Adb
db#
4
0246
#AdB
db#
5
02467
#AdBd
b#
6
024678
#AdBdb
#
9
0246
#AdB
#
10
01
#S
#
acc
3、根据程序设计语言的
般要求,
为定义条件语句的二义文法
G(S)构造SLR
(1)分析表,
要求写出步骤和必要的说明。
G(S):
s—iSeS|iS|a
解答
将文法G(S)拓广为G(S'):
(0)S'—S
(1)S—iSeS
⑵S—iS
⑶S—a
构造此文法的LR(O)项目集规范族,识别该文法所产生的活前缀的DFA如图4.2所示。
图4”2识別活前缀的DFA
注意到状态丨4存在“移进—归约”冲突,计算FOLLOW集合:
FOLLOW(S)={e,#}
当LR分析器处于状态4时,如果下一输入符号是“#”,则按S—iS归约;如果下一输入符号是“e”,则既可以按S—iS归约,也可以执行移入。
根据程序设计语言的要求,条件语句的else子句应当和最近的没有else子句的if语句匹配,根据这一要求,我们规定:
当LR分析器处于状态4时,如果下一输入符号是“#”,则按S—iS归约;如果下一输入符号是“e”,则执行移入。
构造SLR
(1)分析表如表4.3所列。
表4.3SLR
(1)分析表
ACTION
GOTO
i
e
a
#
-S
0
s2
s3
1
1
acc
2
s2
s3
4
3
r3
r3
4
s5
r2
5
s2
s3
6
6
r1
r1
4、设下列文法生成变量的类型说明:
D—idL
L—,idL|:
T
T—integer|real
构造一个翻译模式,把每个标识符的类型存入符号表。
解题思路
这是一个对说明语句进行语义分析的题目,不需要产生代码,但要求把每个标识符的类型填入符号表中。
解答
对D,L,T设置综合属性type。
过程addtype(id,type)用来把标识符id及其类型type填入到符号表中。
翻译模式如下:
DfidL{addtype(id.entry,L.type)}
Lf,idL1{addtype(id.entry,L1.type);L.type:
=L1.type;}
Lf:
T{L.type:
=T.type}
Tfinteger{T.type:
=interger}
Tfreal{T.type:
=real}
5、文法G的产生式如下:
Sf(L)|a
LfL,S|S
(1)试写出一个语法制导定义,它输出配对括号个数;
(2)写一个翻译方案,打印每个a的嵌套深度。
如((a),a),打印2,1。
解题思路
本题包括两部分,第1部分要求写语法制导定义,第2部分要求写翻译方案。
语法制导定义(或属性文法)可以看作是关于语言翻译的高级规范说明,其中隐去实现细节,使用户从明确说明翻译顺序的工作中解脱出来。
翻译方案(也称翻译模式)给出了使用语义规则进行计算的次序,把某些实现细节表示出来。
读者从下面解答中可体会两者的区别。
解答
(1)为S、L引入属性h,代表配对括号个数。
语法制导定义如下:
产生式语义规则
Sf(L)S.h:
=L.h+1
SfaS.h:
=0
LfL1,SL.h:
=L1.h+S.h
LfSL.h:
=S.h
S'fSprint(S.h)
(2)为S、L引入d,代表a的嵌套深度。
翻译方案如下:
S'f{S.d:
=0;}S
Sf‘('{L.d:
=S.d+1;}
L
‘)'
Sfa{print(S.d);}
Lf{L1.d:
=L.d;}
L1
{S.d:
=L.d;}
S
Lf{S.d:
=L.d}
S
6、下列文法对整型常数和实型常数施用加法运算符“+”生成表达式;当两个整型数相加时,结果仍为整型数,否则,结果为实型数:
EfE+T|T
Tfnum.num|num
(1)试给出确定每个子表达式结果类型的属性文法。
(2)扩充
(1)的属性文法,使之把表达式翻译成后缀形式,同时也能确定结果的类型。
应该注意使用一元运算符inttoreal把整型数转换成实型数,以便使后缀形如加法运算符的两个操作数具有相同的类型。
解题思路
确定每个子表达式结果类型的属性文法是比较容易定义的。
关键是如何扩充此属性文法,使之把表达式翻译成后缀形式。
我们将不在name或num.num向T
归约的时候输出该运算对象,而是把运算对象的输出放在T或E+T向E归约的
时候。
这是因为考虑输出类型转换算符inttoreal的动作可能在E+T归约的时
候进行,如果这时两个运算对象都在前面name或num.num向T归约的时候已输出,需要为第1个运算对象输出类型转换算符时就已经为时太晚。
还要注意的是,在E+T向E归约时,该加法运算的第1个运算对象已经输出。
所以E-E+T的语义规则不需要有输出E运算对象的动作。
解答
(1)为文法符号E和T配以综合属性type,用来表示它们的类型。
类型值分别用int和real来表示。
确定每个子表达式结果类型的属性文法如下:
产生式
E-E1+T
E-T
语义规则
{T.type:
=ifE1.type=intandT.type=intthenintelsereal
{E.type:
=T.type}
T-num.numT.type:
=real
T-numT.type:
=int
(2)下面属性文法将表达式的后缀表示打印输出,其中lexeme属性表示单词的拼
写。
产生式语义规则
E-E1+TifE1.type=realandT.type=intthen
begin
E.type:
=real;print(T.lexeme);print(‘inttoreal');
end
elseifE1.type=intandT.type=realthenbegin
E.type:
=real;
print(‘inttoreal');
print(T.lexeme);
end
elsebegin
E.type:
=E1.type;print(T.lexeme);end
print(‘+');
E-TE.type:
=T.type;print(T.lexeme);
T-num.numT.type:
=real;T.lexeme:
=num1.lexeme||“.”||num2.lexeme
T-numT.type:
=int;T.lexeme:
=num.lexeme;
1:
构造如下给定的文法的预测分析表
SAB
A►Ba
B►Db|D
D——►d|&
解:
因为原文法存在左因子
先消除作因子:
将A的产生式代入S
S►BaB|B
提取左因子SBA'A——►aB
引入非终结符号B►DB'B'一|&
消除无用的产生式A——►Ba|&
得到文法:
S——►BA'
A►aB|&
B►DB'
B'►b|&
D►d|&
FIRST(D)={d,&}FIRST(B')={b,&}FIRST(B)={b,d,&}FIRST(A')={a,&}
FIRST(S)={a,b,d,&}FIRST(BA')={a,b,d,&}FIRST(aB)={a}FIRST(DB')={b,d,&}FOLLOW(S)={#}FOLLOW(A')={#}FOLLOW(B)={a,#}FOLLOW(B')={a,#}
FOLLOW(D)={a,b,#}
改写后文法的预测分析表:
a
b
d
#
S
S―►BA'
S―►BA'
S►BA'
S►BA'
A'
A-aB
A'►&
B
BkDB'
BDB
B~DB
BDB
B'
B►&
B'kb
B&
D
D►&
D►&
D―►d
D►&
因为预测分析表无冲突,所以改写后的文法是LL
(1)文法。
2:
判断下列文法可否改写为LL
(1)文法:
SA|B
AaA|a
B►bB|b
因为有左因子•所以原文法不是LL
(1)文法.
改写文法,提取左因子,提取文法:
SA|B
AkaA|&
AA|&
BkbB'
B'►B|£
求FIRSTT集和FOLLOW集
FIRST(B)={b}FIRST(B')={b,£}FIRST(B)={b,d,£}FIRST(A')={a,£}
FIRST(A)={a}FIRST(S)={a,b}FIRST(aB)={a}FIRST(DB')={b,d,£}FOLLOW(S)={#}FOLLOW(A')=FOLLOW(A)=FOLLOW(B)=FOLLOW(B')={#}因为:
FIRST(A)AFIRST(B)=Q
FIRST(A)AFIRST(A')=Q£FIRST(A)
FIRST(B)AFOLLOW(B')=Q£FIRST(B)
所以改写后的文法是LL
(1)文法。
3:
S—i|(E)
E——►E+S|E-S|S
解:
因为原文法有左递归和左因子•所以不是LL
(1)文法.
先消去E的产生式中的左递归:
ESE'
E'—E'|-SE'|£
得到文法:
Si|(E)
E——►SE'
E'—E'|-SE'|£
求FIRST()集和FOLLOW()集
FIRST(S)={i,(}
FIRST(E)=FIRST(SE')={i,(}
FIRST(E')={+,-,&}
FOLLOW(S)={+,-,),#}
FOLLOW(E)={)}
FOLLOW(E')={)}
FIRST(i)AFIRST((E))=①
FIRST(+SE)AFIRST(-SE)=①
£FIRST(+SE)£FIRST(-SE)
FOLLOW(E')FIRST(+SE),FIRST(-SE)
4:
求以下文法中各个非终结符号的
A►baB|&
BFbb|a
解:
FIRST(A)={b,&}
FIRST(B)={a,b}
FOLLOW(A)={b,#}
FOLLOW(B)={b,#}
改写文法消除左递归:
FIRST()集和FOLLOW()集
所以改写后的文法是LL
(1)文法.
M►MaH|H
Hb(M)|(M)|b
解引入M得到文法
M—HM
M—M|£
Hb(M)|(M)|b
此文法中不含左递归,但是关于H的产生式中含左因子,提取左因子得到文法
M—HMI,
M—M|£
HbH|(M)
H'►(M)|£
五:
构造如下给定文法的递归子程序:
S—a|f|(T)
TT,S|S
解:
引入「,消除左递归得到文法
S—►a||(T)
T►ST,
T'——T,|£
FIRST(S)={a,,(}
FIRST(T)=FIRST(S)FIRST(T,)={,£}FOLLOW(S)={,),#}FOLLOW(T)=FOLLOW(T,)={)}
因为FIRST(a),FIRST(f),FIRST((T))两两相交为①FIRST(,ST,)AFOLLOW(T,)=①£FIRST(,ST,)
所以改写后的文法是LL
(1)文法.
语法图:
T,
将T'代入T化简得到:
S的递归子程序:
ProcedureS
Begin
Iflookhead=''thenmatch(a'
Elseiflookhead='f'henmatach(T'
Elseiflookhead='('henBegin
Match('(');
Match(')'
end
end;
T递归子程序:
ProcedureT;
begin
S;
Whilelookhead='(do
Begin
Match(
S;Match()';
End
End;
主程序:
Begin
Lookhead==nexttoken;
S
End;
Match的子程序:
Procedurematch(t.token);
Begin
Iflookhead=tthen
Lookhead:
=nexttoken
Else
Error出错程序处理
End
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 TopDowntBottomUp 习题 解答