编译原理与实践教程黄贤英王柯柯编著习题答案解析.docx
《编译原理与实践教程黄贤英王柯柯编著习题答案解析.docx》由会员分享,可在线阅读,更多相关《编译原理与实践教程黄贤英王柯柯编著习题答案解析.docx(30页珍藏版)》请在冰豆网上搜索。
编译原理与实践教程黄贤英王柯柯编著习题答案解析
第2章参考答案:
1,2,3:
解答:
略!
4.解答:
A:
① B:
③ C:
① D:
②
5.解答:
用E表示<表达式>,T表示<项>,F表示<因子>,上述文法可以写为:
E→T|E+T
T→F|T*F
F→(E)|i
最左推导:
E=>E+T=>E+T+T=>T+T+T=>F+T+T=>i+T+T=>i+F+T=>i+i+T
=>i+i+F=>i+i+i
E=>E+T=>T+T=>F+T=>i+T=>i+T*F=>i+F*F=>i+i*F=>i+i*i
最右推导:
E=>E+T=>E+F=>E+i=>E+T+i=>E+F+i=>E+i+i=>T+i+i
=>F+i+i=>i+i+i
E=>E+T=>E+T*F=>E+T*i=>E+F*i=>E+i*i=>T+i*i=>F+i*i=>i+i*i
i+i+i和i+i*i的语法树如下图所示。
i+i+i、i+i*i的语法树
6.解答:
(1)终结符号为:
{or,and,not,(,),true,false}
非终结符号为:
{bexpr,bterm,bfactor}
开始符号为:
bexpr
(2)句子not(trueorfalse)的语法树为:
7.解答:
(1)把anbnci分成anbn和ci两部分,分别由两个非终结符号生成,因此,生成此文法的产生式为:
S→AB
A→aAb|ab
B→cB|
(2)令S为开始符号,产生的w中a的个数恰好比b多一个,令E为一个非终结符号,产生含相同个数的a和b的所有串,则产生式如下:
S→aE|Ea|bSS|SbS|SSb
E→aEbE|bEaE|
(3)设文法开始符号为S,产生的w中满足|a|≤|b|≤2|a|。
因此,可想到S有如下的产生式(其中B产生1到2个b):
S→aSBS|BSaS
B→b|bb
(4)解法一:
S→〈奇数头〉〈整数〉〈奇数尾〉
|〈奇数头〉〈奇数尾〉
|〈奇数尾〉
〈奇数尾〉→1|3|5|7|9
〈奇数头〉→2|4|6|8|〈奇数尾〉
〈整数〉→〈整数〉〈数字〉|〈数字〉
〈数字〉→0|〈奇数头〉
解法二:
文法G=({S,A,B,C,D},{0,1,2,3,4,5,6,7,8,9},P,S)
S→AB|B
A→AC|D
B→1|3|5|7|9
D→2|4|6|8|B
C→0|D
(5)文法G=({N,S,N,M,D},{0,1,2,3,4,5,6,7,8,9},S,P)
S→N0|N5
N→MD|
M→1|2|3|4|5|6|7|8|9
D→D0|DM|
(6)G[S]:
S→aSa|bSb|cSc|a|b|c|
8.解答:
(1)句子abab有如下两个不同的最左推导:
S=>aSbS=>abS=>abaSbS=>ababS=>abab
S=>aSbS=>abSaSbS=>abaSbS=>ababS=>abab
所以此文法是二义性的。
(2)句子abab的两个相应的最右推导:
S=>aSbS=>aSbaSbS=>aSbaSb=>aSbab=>abab
S=>aSbS=>aSb=>abSaSb=>abSab=>abab
(3)句子abab的两棵分析树:
(a)
(b)
(4)此文法产生的语言是:
在{a,b}上由相同个数的a和b组成的字符串。
9,10:
解答:
略!
第3章习题解答:
1.解答:
(1) √
(2) √ (3) ×(4) × (5) √ (6)√
2.[分析]
有限自动机分为确定有限自动机和非确定有限自动机。
确定有限自动机的确定性表现在映射:
Q×VT-->q是单值函数,也就是说,对任何状态q∈Q和输入字符串a∈VT,(q,a)唯一确定下一个状态。
显然,本题给出的是一个确定的有限自动机,它的状态转换图是C中的②。
它所接受的语言可以用正则表达式表示为00(0|1)*,表示的含义为由两个0开始的后跟任意个(包含0个)0或1组成的符号串的集合。
2.解答:
A:
④ B:
③ C:
② D:
② E:
④
3,4.解答:
略!
5.解答:
6.解答:
(1)(0|1)*01
(2)((1|2|…|9)(0|1|2|…|9)*|)(0|5)
(3)(0|1)*(011)(0|1)*
(4)1*|1*0(0|10)*(1|)
(5)a*b*c*…z*
(6)(0|10*1)*1
(7)(00|11)*((01|10)(00|11)*(01|10)(00|11)*)*
(8)[分析]
设S是符合要求的串,|S|=2k+1(k≥0)。
则S→S10|S21,|S1|=2k(k>0),|S2|=2k(k≥0)。
且S1是{0,1}上的串,含有奇数个0和奇数个1。
S2是{0,1}上的串,含有偶数个0和偶数个1。
考虑有一个自动机M1接受S1,那么自动机M1如下:
和L(M1)等价的正规式,即S1为:
((00|11)|(01|10)(00|11)*(01|10))*(01|10)(00|11)*
类似的考虑有一个自动机M2接受S2,那么自动机M2如下:
和L(M2)等价的正规式,即S2为:
((00|11)|(01|10)(00|11)*(01|10))*
因此,S为:
((00|11)|(01|10)(00|11)*(01|10))*(01|10)(00|11)*0|
((00|11)|(01|10)(00|11)*(01|10))*1
7.解答:
(1) 以0开头并且以0结尾的,由0和1组成的符号串。
(2) {|∈{0,1}*}
(3) 由0和1组成的符号串,且从右边开始数第3位为0。
(4) 含3个1的由0和1组成的符号串。
{|∈{0,1}+,且中含有3个1}
(5) 包含偶数个0和1的二进制串,即{|∈{0,1}*,且中有偶数个0和1}
8.解答:
0
1
Q0*
Q1
Q2
Q3
Q2
Q3
Q0
Q1
Q1
Q0
Q3
Q2
9.解答:
(1)DFA M=({0,1},{q0,q1,q2},q0,{q2},)
其中定义如下:
(q0,0)=q1 (q0,1)=q0
(q1,0)=q2 (q1,1)=q0
(q2,0)=q2 (q2,1)=q0
状态转换图为:
(2)正规式:
1*01*01*01*
DFA M=({0,1},{q0,q1,q2,q3},q0,{q3},),其中定义如下:
(q0,0)=q1 (q0,1)=q0
(q1,0)=q2 (q1,1)=q1
(q2,0)=q3 (q2,1)=q2
(q3,1)=q3
状态转换图为:
10.解答:
(1) DFA M=({0,1},{q0,q1,q2,q3},q0,{q3},),其中定义如下:
(q0,0)=q1 (q0,1)=q2
(q1,0)=q1 (q1,1)=q3
(q2,0)=q3 (q2,1)=q1
状态转换图为:
(2)DFA M=({0,1},{q0},q0,{q0},),其中定义如下:
(q0,0)=q0 (q0,1)=q0
状态转换图为:
11解答:
(1)(a|b)*a(a|b)
①求出NFAM:
②确定化,得到DFAM:
③化简:
在第②步中求出的DFAM中没有等价状态,因此它就是最小化的DFAM。
(2)(a)b)*a(a|b)(a|b)
①求NFAM:
②确定化,得到DFAM:
③化简,在第②步中求出的DFAM中没有等价状态,因此它已经是最小化的DFAM了。
12.解答:
对应的NFA为:
增加状态X、Y,再确定化:
I
Ia
Ib
{x,5}
{A,T,Y}
{}
{A,T,Y}
{A,T,Y}
{B}
{B}
{}
{B,T,Y}
{B,T,Y}
{}
{T,Y}
{T,Y}
{}
{}
得到的DFA为:
最小化:
该自动机已经是最小化的DFA了。
13.解答:
其中a代表1元硬币,b代表5角硬币
14.解答:
正规式为:
(0|1)*(00|01)化简:
(0|1)*0(0|1)
不确定的有穷自动机为:
确定化,并最小化得到:
正规文法为:
S→1S|0A
A→0B|0|1C|1
B→0B|0|1C|1
C→1S|0A
15.解答:
①正规式:
(dd*:
|)dd*(.dd*|),d代表a~z的字母
②NFA为:
③DFA为:
16.解答:
词法分析器对源程序采取非常局部的观点,因此象C语言的语句
fi(a==f(x))…
中,词法分析器把fi当作一个普通的标识符交给编译的后续阶段,而不会把它看成是关键字if的拼写错。
PASCAL语言要求作为实型常量的小数点后面必须有数字,如果程序中出现小数点后面没有数字情况,它由词法分析器报错。
17.解答:
此时编译器认为
/*thenpart
returnq
else
/*elsepart*/
是程序的注释,因此它不可能再发现else前面的语法错误。
分析这是注释用配对括号表示时的一个问题。
注释是在词法分析时忽略的,而词法分析器对程序采取非常局部的观点。
当进入第一个注释后,词法分析器忽略输入符号,一直到出现注释的右括号为止,由于第一个注释缺少右括号,所以词法分析器在读到第二个注释的右括号时,才认为第一个注释处理结束。
为克服这个问题,后来的语言一般都不用配对括号来表示注释。
例如Ada语言的注释始于双连字符(--),随行的结束而终止。
如果用Ada语言的注释格式,那么上面函数应写成
longgcd(p,q)
longp,q;
{
if(p%q==0)
--thenpart
returnq
else
--elsepart
returngcd(q,p%q);
}
18.解答:
略!
第4章习题解答:
1,2,3,4解答略!
5.解答:
(1)×
(2)√(3)×(4)√(5)√(6)√(7)×(8)×
6.解答:
(1)A:
④B:
③C:
③D:
④E:
②
(2)A:
④B:
④C:
③D:
③E:
②
7.解答:
(1)消除给定文法中的左递归,并提取公因子:
bexpr→bterm{orbterm}
bterm→bfactor{andbfactor}
bfactor→notbfactor|(bexpr)|true|false
(2)用类C语言写出其递归分析程序:
voidbexpr();
{
bterm();
WHILE(lookahead=='or'){
match('or');
bterm();
}
}
voidbterm();
{
bfactor();
WHILE(lookahead=='and'){
match('and');
bfactor();
}
}
voidbfactor();
{
if(llokahead=='not')then{
match('not');
bfactor();
}
elseif(lookahead=='(')then{
match(‘(');
bexpr();
match(')');
}
elseif(lookahead=='true')
then match('true)
elseif(lookahead=='false')
thenmatch('false');
elseerror;
}
8.解答:
消除所给文法的左递归,得G':
S→(L)|a
L→SL'
L'→,SL'|
实现预测分析器的不含递归调用的一种有效方法是使用一张分析表和一个栈进行联合控制,下面构造预测分析表:
根据文法G'有:
First(S)={(,a)Follow(S)={),,,#}
First(L)={(,a)Follow(L)={)}
First(L')={,}Follow(L')={)}
按以上结果,构造预测分析表M如下:
文法G'是LL
(1)的,因为它的LL
(1)分析表不含多重定义入口。
预测分析器对输入符号串(a,(a,a))做出的分析动作如下:
步骤
栈
剩余输入串
输出
1
#S
(a,(a,a))#
#
2
#)L(
a,(a,a))#
S→(L)
3
#)L
a,(a,a))#
4
#)L'S
a,(a,a))#
L→SL'
5
#)L'a
a,(a,a))#
S→a
6
#)L'
(a,a))#
7
#)L'S,
(a,a))#
L'→,SL'
8
#)L'S
(a,a))#
9
#)L')L(
(a,a))#
S→(L)
10
#)L')L
a,a))#
11
#)L')L'S
a,a))#
L→SL'
12
#)L')L'a
a,a))#
S→a
13
#)L')L'
a))#
14
#)L')L'S,
a))#
L'→,SL'
15
#)L')L'S
a))#
16
#)L')L'a
a))#
S→a
17
#)L')L'
))#
18
#)L')
))#
L'→
19
#)L'
)#
20
#)
)#
L'→
21
#
#
9.解答:
各非终结符的First集:
First(S)={First(A)\{}}∪{First(B)\{}}∪{}∪{b}={a,b,}
First(A)={b}∪{}={b,}
First(B)={}∪{a}={a,}
First(C)={First(A)\{}}∪First(D)∪First(b)={a,b,c}
First(D)={a}∪{c}={a,c}
各个候选式的First集为:
First(AB)={a,b,}First(bC)={b}
First()={}First(b)={b}
First(aD)={a}First(AD)={a,b,c}
First(b)={b}First(aS)={a}
First(c)={c}
各非终结符的Follow集的计算:
Follow(S)={#}∪Follow(D)={#}
Follow(A)=(First(B)\{})∪Follow(S)∪First(D)={a,#,c}
Follow(B)=Follow(S)={#}
Follow(C)=Follow(S)={#}
Follow(D)=Follow(B)∪Follow(C)={#}
10.解答:
(1)求First和Follow集
First(E)=First(T)={(,a,b,∧}⑦
First(E')={+,}⑥
First(T)=First(F)={(,a,b,∧}④
First(T')={(,a,b,∧,}⑤
First(F)=First(P)={(,a,b,∧}③
First(F')={*,}②
First(P)={(,a,b,∧}①(计算顺序)
Follow(E)={#,)}
Follow(E')=Follow(E)={#,)}
(1)(使用的产生式)
Follow(T)=First(E')\{}∪Follow(T')(1,2)
={+}∪{),#}={+,),#}
Follow(T')=Follow(T)={+,},#}(3)
Follow(F)=First(T')\{}∪Follow(T)(3,4)
={(,a,b,∧,+,),#}
Follow(F')=Follow(F)(5)
={(,a,b,∧,+,),#}
Follow(P)=First(F')\{}∪Follow(F)(5,6)
={*,(,a,b,∧,+,),#}
(2)证明:
∵a.文法不含左递归;
b.每个非终结符的各个侯选式的First集不相交;
c.First(E')∩Follow(E')={+,}∩{#,),}=
First(T')∩Follow(T')={(,a,b,∧,}∩{+,)}=
First(F')∩Follow(F')={*,}∩{,a,(∧,+,},#}=
∴改造后的文法满足LL
(1)文法的三个条件,是LL
(1)文法。
(3)预测分析表如下所示。
a
b
*
+
∧
(
)
#
E
E→TE'
E→TE'
E→TE'
E'
E'→+E
E'→
E'→
T
T→FT'
T→FT'
T→FT'
T→FT'
T'
T'→T
T'→T
T'→T
T'→T
T'→
T'→
F
F→PF'
F→PF'
F→PF'
F→PF'
F'
F'→
F'→
F'→*F'
F'→
F'→
F'→
F'→
F'→
P
P→a
P→b
P→∧
P→(E)
11.解答:
(1)
S→Abc
A→a│
B→b│
a.文法不含左递归;
b.S,A,B各候选式的First集不相交;
c.First(A)∩Follow(A)={a,}∩{b}=
First(B)∩Follow(B)={b,}∩=
∴该文法为LL
(1)文法。
(2)
S→Ab
A→a│B│
B→b│
a.文法不含左递归;
b.S,A,B各候选式的First集不相交;
c.First(A)∩Follow(A)={a,b,}∩{b}={b}≠
∴该文法不是LL
(1)文法。
12.解答:
①最右推导:
E=>T=>F=>(E)=>(E+T)=>(E+F)=>(E+i)=>(T+i)=>(T*F+i)
语法树:
图4.1句型(T*F+i)的语法树
②短语:
(T*F+i),T*F+i,T*F,i
素短语:
T*F,i
最左素短语:
T*F
③由于E=>E+T=>E+T*F,故E+T*F为该文法的句型
短语:
T*F、E+T*F
直接短语:
T*F
句柄:
T*F
13.解答:
最左推导:
S=>(T)=>(T,S)=>(S,S)=>(a,S)=>(a,(T))=>(a,(T,S))
=>(a,(S,S))=>(a,(a,S))=>(a,(a,a))
最右推导:
S=>(T)=>(T,S)=>(T,(T))=>(T,(T,S))=>(T,(T,a))
=>(T,(T,a))=>(T,(a,a))=>(S,(a,a))=>(a,(a,a))
文法中S和T的FirstVT和LastVT集为:
FirstVT(S)={a,(}FirstVT(T)={,,a,(}
lastVT(S)={a,)}lastVT(T)={,,a,)}
文法G[S]的算符优先关系表:
根据优先关系表,对每个终结符或#建立符号f与g,把f(和g)分成一组。
根据G[S]的算符优先关系表,画出如下的有向图。
优先函数如下:
用算符优先分析法分析句子(a,(a,a))。
给定的输入符号串是文法的一个句子。
14.解答:
(1)该文法的拓广文法G'为
0.S'→S
1.S→aSAB
2.S→BA
3.A→aA
4.A→B
5.B→b
其LR(0)项目集规范族和识别活前缀的DFA如下:
I0={S'→·S,S→·aSAB,S→·BA,B→·b}
I1={S'→S·}
I2={B→b·}
I3={S→a·SAB,S→·aSAB,S→·BA,B→·b}
I4={S→B·A,A→·aA,A→·B,B→·b}
I5={S→aS·AB,A→·aA,A→·B,B→·b}
I6={S→aSA·B,B→·b}
I7={A→a·A,A→·aA,A→·B,B→·b}
I8={A→B·}
I9={S→BA·}
I10={S→aSAB·}
I11={A→aA·}
显然,上述状态中没有出现冲突。
显然,该文法是LR(0)的文法,因此也是SLR
(1)的。
求各个非终结符的Follow集,以便构造分析表:
Follow(S')={#} Follow(S)={a,b,#}
Follow(A)={a,b,#} Follow(B)={a,b,#}
构造的SLR
(1)分析表如下:
(2)该文法的拓广文法G'为
0.S'→S
1.S→Sab
2.S→bR
3.R→S
4.R→a
其LR(0)项目集规范族和识别活前缀的DFA如下:
I0={S'→·S,S→·Sab,S→·bR}
I1={S'→S·,S→S·ab}
I2={S→b·R,R→·S,R→·a,S→·Sab,S→·bR}
I3={S→Sa·b}
I4={S→bR·}
I5={R→S·,S→S·ab}
I6={R→a·}
I7={S→Sab·}
显然,I1和I5存在移进-归约冲突。
求S'和R的Follow集:
Follow(S')={#}
Follow(R)=Follow(S)={a,#}
在I5中,出现的移进-归约冲突,且Follow(R)∩{a}={a},不能用SLR
(1)方法解决。
因此,此文法不是SLR
(1)文法。
15.解答:
(1)构造其拓广文法G'的产生式为
0