(完整版)编译原理第五章作业参考答案

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
FIRST(S)={a,人,(}
FIRST(T)=FIRST(S)={a,人,(}
FIRST(U)={,,£}
各非终结符的FOLLOW!合如下:
FOLLOW(S)={#}UFIRST(U)UFOLLOW(T)UFOLLOW(U)={#,,,)}
FOLLOW(T)={)}
FOLLOW(U)=FOLLOW(T)={)}
IF CH=yi THEN READ(CH) ELSE ERROR
即如果当前文法中的符号与输入符号匹配,则继续读入下一个待输入符号到CH中,
否则表明出错。
⑷如果文法中有空规则U::=EPSILON,则算法中的语句
IF CH IN FIRST(x n) THEN P(x n)
ELSE ERROR
改写为:
(1)对于每个非终结号U,编写一个相应的子程序P(U);
(2)对于规则U::=x1|x2|..|xn,有一个关于U的子程序P(U),P(U)按如下方法构造:
IF CH IN FIRST(x1) THEN P(x1)
ELSE IF CH IN FIRST(x2) THEN P(x2)
ELSE ...
IF CH IN FIRST(x n) THEN P(x n)
每个产生式的SELECT集合如下:
SELECT(S a)={a}
SELECT(SA)={A}
SELECT(S (T))={(}
SELECT(T SU)=FIRST(S)={a,A,(}
SELECT(U,SU)={,}
SELECT(Ue)=FOLLOW(U)={)}
可见,相同左部产生式的SELECT集的交集均为空,所以文法G[S]是LL(1)文法
(((T,S),A,(a)),a)
(((S,a),
A,(a)),a)
(((a,a),
A,(a)),a)
⑵由于有T T,S的产生式,所以消除该产生式的左递归,增中一个非终结符U有新的文法G[S]:
S a|A|(T)
T SU
U,SU|£
分析子程序的构造方法
对满足条件的文法按如下方法构造相应的语法分析子程序。
解:
(1) (a,(a,a))
的最左推导为
S (T)
(T,S)(S,S)
(a,(T))
(a,(T,S))
(a,(S,a))
(a,(a,a))
(((a,a),
A,(a)),a)的最左推导为
S (T)
(T,S)(S,a)
((T),a)
((T,S),a)
((T,S,S),a)
((S,
A,(T)),a)
(((T),A,(S)),a)
FIRST(T/)=FIRST(T)U{e}={(,a,b=e};
FIRST(F)=FIRST(P)={(,a,b,A};
FIRST(F)=FIRST(P)={*,£};
ELSE ERROR
其中,CH存放当前的输入符号,是一个全程变量;ERROR1一段处理岀错信息的程序;
P(xj)为相应的子程序。
⑶对于符号串x=y1y2...y n;p(x)的含义为:
BEGIN
P(y1);
P(y2);
P(y n);
END
如果yi是非终结符,则P(yi)代表调用处理yi的子程序;
如果yi是终结符,则P(yi)为形如下述语句的一段子程序
对每个非终结符写出不带回溯的递归子程序如下:
char CH;//存放当前的输入符号
void P_S()〃非终结符S的子程序
{
if(CH=='aREAD(CH);//产生式S a
else if(CH=='A') READ(C产生式SA
else if(CH=='产'生式S (T)
{
READ(CH);
P_T();
文法G[S]的预测分析表如下:
a
A
(
)
#
S
a
A
(T)
T
SU
SU
SU
U
e
,SU
(5)给岀输入串(a,a)#的分析过程
步骤
分析栈
剩余输入串
所用产生式
1
#S
(a,a)#
S (T)
2
#)T(
(a,a)#
(匹配
3
#)T
a,a)#
T SU
4
#)US
a,a)#
S a
5
#)Ua
a,a)#
a匹配
6
#)U
,a)#
U,SU
IF CH IN FIRST(x n) THEN P(x n)
ELSE IF CH IN FOLLOW(U) THEN RETURN
ERROR
(5) 要分析一个OrgStr,应在该串的后面加上一个串括号’#',并从子程序P(S)(S为文法的开始符号
如果中途没有产生错误,并且最后CH='#',则说明OrgStr串合法,否则该串不合法。
第五章 自顶向下语法分析方法
1•对文法G[S]
S a|A|(T)
T T,S|S
(1)给岀(a,(a,a))和(((a,a),A,(a)),a)的最左推导。
(2)对文法G,进行改写,然后对每个非终结符写出不带回溯的递归子程序。
(3)经改写后的文法是否是LL(1)的?给岀它的预测分析表。
(4)给岀输入串(a,a)#的分析过程,并说明该串是否为G的句子。
IF (CH= =') THEN READ(CH) else ERROR
}
else ERR;
}
void P_T()//非终结符S的子程序
{
if(IsIn(CH,FIRST_SU))〃FIRST_SU为T SU的右部的FIRST集合
{
P_S();
P_U();
}
}
void P_U()//非终结符U的子程序
7
#)US,
,a)#
,匹配
8
#)US
a)#
S a
9
#)Ua
a)#
a匹配
10
#)U
)#
Ue
11
#)
)#
)匹配
12
#
#
接受
2.对下面的文法G:
E TE
E +E|e
T FT
T/T|e
f pF
F/*F/|e
P (E)|a|bF
(1)计算这个文法的每个非终结符的FIRST集和FOLLOW!。
⑵证明这个方法是LL(1)的。
(3)构造它的预测分析表。
(4)构造它的递归下降分析程序。
解:பைடு நூலகம்
(1)计算这个文法的每个非终结符的FIRST集和FOLLOW集。
FIRST集合有:
FIRST(E)=FIRST(T)=FIRST(F)=FIRST(P)={(,a,br};
FIRST(E/)={+,e}
FIRST(T)=FIRST(F)=FIRST(P)={(,a,br};
{
if(CH==',产生式U,SU
{
READ(CH);
P_S();
P_U();
}
else//产生式U£
{
if(IsIn(CH,FOLLOW_U)) //FOLLOW_U为U的FOLLOW集合
return ;
else ERR;
}
}
⑶判断文法G[S]是否为LL(1)文法。
各非终结符的FIRST集合如下:
相关文档
最新文档