编译原理第五章
- 格式:docx
- 大小:22.51 KB
- 文档页数:4
练习5.1解答:输入(4*7+1)*2n,带注释的分析树如下:练习5.2解答: (1)根据表5.3中的语法制导定义建立表达式((a)+(b))的分析树和语法树(2)根据图5.17的翻译模式构造((a)+(b))的分析树和语法树练习5.3解答:设置下面的函数和属性:expr1||expr2:把表达式expr2拼写在表达式expr1后面。
deletep(expr):去掉表达式expr左端的‘(’和右端的‘)’。
E.expr,T.expr,F.expr:属性变量,分别表示E,T,F的表达式。
E.add,T.add,F.add,属性变量,若为true,则表示其表达式中外层有‘+’号,否则无‘+’号。
E.pmark,T.pmark,F.pmark,属性变量,若为true,表示E,T,F的表达式中左端为‘(’,右端是‘)’。
语法制导定义如下:产生式语义规则E -> E1 +T if(T.pmark==true)THEN E.expr=E1.expr||'+'||deletep(T.expr) ELSE E.expr:=E1.expr||'+'||T.expr;E.add:=true;E.pmark:=false;E -> T if(T.pmark==true)THEN E.expr:=deletep(T.expr)ELSE E.expr:=T.expr;E.add:=T.add;E.pmark:=false;T -> T1*F T.expr:=T1.expr||'*'||F.expr; T.add:=false;T.pmark:=false;T -> F T.expr:=F.expr; T.add:=F.add;T.pmark:=F.pmark;F -> (E) if(E.add==false)THEN BEGINF.expr:=E.expr;F.add:=false;F.pmark:=false;ENDELSE BEGINF.expr:='('||E.expr||')';F.add:=true;F.pmark:=true;END;F -> id F.expr:=id.lexval;F.add:=false;F.pmark:=false;练习5.4解答: (1)语法制导定义如下:产生式语义规则E -> E1+T if(E1.type==int) AND (T.type==int) THEN E.type:=intELSE E.type:=real;E -> T E.type:=T.type;T -> num T.type:=int;T -> num.num T.type:=real;(2)设E.pf和T.pf分别是E和T的前缀形式,||是两个字符串的连接,语法制导定义如下:产生式语义规则E -> E1+T if(E1.type==int) AND (T.type==int)THEN E.type:=intELSE BEGINE.type:=real;if(E1.type==int) AND (T.type==real)THEN E1.pf:='inttoreal'||E1.pfELSE if(E1.type==real)AND(T.type==int)THEN T.pf:='inttoreal'||T.pfEND;E.pf:='+'||E1.pf||T.pf;E -> T E.type:=T.type; E.pf:=T.pf;T -> num T.type:=int; T.pf:=int.lexval;T ->num.numT.type:=real; T.pf:=real.lexval;练习5.5解答: (1)用综合属性决定s.val的语法制导定义:产生式语义规则S -> L S.val:=L.val;S ->L1.L2S.val:=L1.val+L2.val*L2.p;L -> B L.val:=B.val; L.p:=2-1;L -> L1B L.val:=L1.val*2+B.val; L.p:=L.p*2-1;B -> 0 B.val:=0;B -> 1 B.val:=1;注:L.p表示恢复L.val的因子。
第五章
2.对下面的文法G:
E→TE/
E/→+E|ε
T→FT/
T/→T|ε
F→PF/
F/→*F/|ε
P→(E)|a|b|^
(1)计算这个文法的每个非终结符的FIRST集和FOLLOW集。
(2)证明这个方法是LL(1)的。
(3)构造它的预测分析表。
(4)构造它的递归下降分析程序。
解:
(1)计算这个文法的每个非终结符的FIRST集和FOLLOW集。
FIRST集合有:
FIRST(E)=FIRST(T)=FIRST(F)=FIRST(P)={(,a,b,^};
FIRST(E/)={+,ε}
FIRST(T)=FIRST(F)=FIRST(P)={(,a,b,^};
FIRST(T/)=FIRST(T)∪{ε}={(,a,b,^,ε};
FIRST(F)=FIRST(P)={(,a,b,^};
FIRST(F/)=FIRST(P)={*,ε};
FIRST(P)={(,a,b,^};
FOLLOW集合有:
FOLLOW(E)={),#};
FOLLOW(E/)=FOLLOW(E)={),#};
FOLLOW(T)=FIRST(E/)∪FOLLOW(E)={+,),#};//不包含ε
FOLLOW(T/)=FOLLOW(T)=FIRST(E/)∪FOLLOW(E)={+,),#};
FOLLOW(F)=FIRST(T/)∪FOLLOW(T)={(,a,b,^,+,),#};//不包含εFOLLOW(F/)=FOLLOW(F)=FIRST(T/)∪FOLLOW(T)={(,a,b,^,+,),#};
FOLLOW(P)=FIRST(F/)∪FOLLOW(F)={*,(,a,b,^,+,),#};//不包含ε(2)证明这个方法是LL(1)的。
各产生式的SELECT集合有:
SELECT(E→TE/)=FIRST(T)={(,a,b,^};
SELECT(E/→+E)={+};
SELECT(E/→ε)=FOLLOW(E/)={),#}
SELECT(T→FT/)=FIRST(F)={(,a,b,^};
SELECT(T/→T)=FIRST(T)={(,a,b,^};
SELECT(T/→ε)=FOLLOW(T/)={+,),#};
SELECT(F→PF/)=FIRST(P)={(,a,b,^};
SELECT(F/→*F/)={*};
SELECT(F/→ε)=FOLLOW(F/)={(,a,b,^,+,),#};
SELECT(P→(E))={(}
SELECT(P→a)={a}
SELECT(P→b)={b}
SELECT(P→^)={^}
可见,相同左部产生式的SELECT集的交集均为空,所以文法G[E]是LL(1)文法。
(3)构造它的预测分析表。
文法G[E]的预测分析表如下:
(4)构造它的递归下降分析程序。
对每个非终结符写出不带回溯的递归子程序如下:
char CH;//存放当前的输入符号
void P_E()//非终结符E的子程序
{
if(IsIn(CH,FIRST_TEP)) //FIRST_TEP为T→TE/ 的右部的FIRST集合,产生式E→TE/
{
P_T();
P_EP();
}
else ERR;
}
void P_EP()//非终结符E/的子程序
{
if(CH==’+’) //产生式E/→+E
{
READ(CH);
P_E();
}
else//产生式E/→ε
{
if(IsIn(CH,FOLLOW_EP)) //FOLLOW_EP为E/的FOLLOW集合
return ;
else ERR;
}
}
void P_T()//非终结符T的子程序
{
if(IsIn(CH,FIRST_FTP)) //FIRST_TEP为T→FT/ 的右部的FIRST集合,产生式T→FT/
{
P_F();
P_TP();
}
else ERR;
}
void P_TP()//非终结符T/的子程序
{
if(IsIn(CH,FIRST_T)) //FIRST_T为产生式T/→T的右部的FIRST集合,产生式T/→T
{
P_T();
}
else//产生式T/→ε
{
if(IsIn(CH,FOLLOW_TP)) //FOLLOW_TP为T/的FOLLOW集合
return ;
else ERR;
}
}
void P_F()//非终结符F的子程序
{
if(IsIn(CH,FIRST_PFP)) //FIRST_PFP为F→PF/ 的右部的FIRST集合,产生式F→PF/
{
P_P();
P_FP();
}
else ERR;
}
void P_FP()//非终结符F/的子程序
{
if(CH==’*’) //产生式F/→*F/
{
READ(CH);
P_FP();
}
else//产生式F/→ε
{
if(IsIn(CH,FOLLOW_FP)) //FOLLOW_FP为F/的FOLLOW集合
return ;
else ERR;
}
}
void P_P()//非终结符P的子程序
{
if(CH==’(‘)
{
READ(CH);
P_E();
if(CH==’)’) READCH(CH);
else
ERR;
}
else if(CH==’a’) READ(CH);
else if(CH==’b’) READ(CH);
else if(CH==’^’) READ(CH);
else ERR;
}
4证明下述文法不是LL(1)的。
S->C$ C->bA|aB A->a|aC|bAA B->b|bC|aBB 你能否构造一等价的文法,使其是LL (1)的,并给出判断过程。
【解】因为SELECT(A->a)∩SELECT(A->aC)≠Ф,根据LL(1)文法的判定条件:(1)文法不含左递归(2)对于文法U的任意两个不同的规则有: Select(U→α) ∩Select(U→)=Φ一个文法若满足以上条件,称该文法G为LL(1)文法。
得出该文法不是LL(1)文法。
该文法含公共因子,消除后的文法为:S->C$ C-> bA|aB A->aA'|bAA A’->C|εB->bB'| aBB
B’->C|ε【证明】因为SELECT(C-> bA) ∩SELECT(C->aB)= ΦSELECT(A->Aa) ∩SELECT(A->bAA) = ΦSELECT(A’->C) ∩SELECT(A’->ε)=(FIRST(C)-{ ε})∩FOLLOW(A’) ≠Ф因此消除公共因子后得到文法也不是LL(1)文法。