编译原理教程课后习题答案第三章.docx

上传人:b****5 文档编号:28966048 上传时间:2023-07-20 格式:DOCX 页数:55 大小:693.88KB
下载 相关 举报
编译原理教程课后习题答案第三章.docx_第1页
第1页 / 共55页
编译原理教程课后习题答案第三章.docx_第2页
第2页 / 共55页
编译原理教程课后习题答案第三章.docx_第3页
第3页 / 共55页
编译原理教程课后习题答案第三章.docx_第4页
第4页 / 共55页
编译原理教程课后习题答案第三章.docx_第5页
第5页 / 共55页
点击查看更多>>
下载资源
资源描述

编译原理教程课后习题答案第三章.docx

《编译原理教程课后习题答案第三章.docx》由会员分享,可在线阅读,更多相关《编译原理教程课后习题答案第三章.docx(55页珍藏版)》请在冰豆网上搜索。

编译原理教程课后习题答案第三章.docx

编译原理教程课后习题答案第三章

第三章语法分析

3.1完成下列选择题:

(1)文法G:

S→xSx|y所识别的语言是。

a.xyxb.(xyx)*

c.xnyxn(n≥0)d.x*yx*

(2)如果文法G是无二义的,则它的任何句子α。

 

a.最左推导和最右推导对应的语法树必定相同

b.最左推导和最右推导对应的语法树可能不同

c.最左推导和最右推导必定相同

d.可能存在两个不同的最左推导,但它们对应的语法树相同

(3)采用自上而下分析,必须。

a.消除左递a.必有ac归b.消除右递归

c.消除回溯d.提取公共左因子

(4)设a、b、c是文法的终结符,且满足优先关系ab和bc,则。

b.必有ca

c.必有bad.a~c都不一定成立

(5)在规范归约中,用来刻画可归约串。

a.直接短语b.句柄

c.最左素短语d.素短语

(6)若a为终结符,则A→α·aβ为项目。

a.归约b.移进

c.接受d.待约

(7)若项目集Ik含有A→α·,则在状态k时,仅当面临的输入符号a∈FOLLOW(A)时,才采取“A→α·”动作的一定是。

a.LALR文法b.LR(0)文法

c.LR

(1)文法d.SLR

(1)文法

(8)同心集合并有可能产生新的冲突。

a.归约b.“移进”/“移进”

c.“移进”/“归约”d.“归约”/“归约”

【解答】

(1)c

(2)a(3)c(4)d(5)b(6)b(7)d(8)d

3.2令文法G[N]为

G[N]:

N→D|ND

D→0|1|2|3|4|5|6|7|8|9

(1)G[N]的语言L(G[N])是什么?

(2)给出句子0127、34和568的最左推导和最右推导。

【解答】

(1)G[N]的语言L(G[N])是非负整数。

(2)最左推导:

NNDNDDNDDDDDDD0DDD01DD012D0127

NNDDD3D34

NNDNDDDDD5DD56D568

最右推导:

NNDN7ND7N27ND27N127D1270127

NNDN4D434

NNDN8ND8N68D68568

3.3已知文法G[S]为S→aSb|Sb|b,试证明文法G[S]为二义文法。

【解答】由文法G[S]:

S→aSb|Sb|b,对句子aabbbb可对应如图3-1所示的两棵语法树。

图3-1句子aabbbb对应的两棵不同语法树

因此,文法G[S]为二义文法(对句子abbb也可画出两棵不同语法树)。

3.4已知文法G[S]为S→SaS|ε,试证明文法G[S]为二义文法。

【解答】由文法G[S]:

S→SaS|ε,句子aa的语法树如图3-2所示。

图3-2句子aa对应的两棵不同的语法树

由图3-2可知,文法G[S]为二义文法。

3.5按指定类型,给出语言的文法。

(1)L={aibj|j>i≥0}的上下文无关文法;

(2)字母表Σ={a,b}上的同时只有奇数个a和奇数个b的所有串的集合的正规文法;

(3)由相同个数a和b组成句子的无二义文法。

【解答】

(1)由L={aibj|j>i≥0}知,所求该语言对应的上下文无关文法首先应有S→aSb型产生式,以保证b的个数不少于a的个数;其次,还需有S→Sb或S→b型的产生式,用以保证b的个数多于a的个数。

因此,所求上下文无关文法G[S]为

G[S]:

S→aSb|Sb|b

(2)为了构造字母表Σ={a,b}上同时只有奇数个a和奇数个b的所有串集合的正规式,我们画出如图3-3所示的DFA,即由开始符S出发,经过奇数个a到达状态A,或经过奇数个b到达状态B;而由状态A出发,经过奇数个b到达状态C(终态);同样,由状态B出发经过奇数个a到达终态C。

由图3-3可直接得到正规文法G[S]如下:

G[S]:

S→aA|bB

A→aS|bC|b

B→bS|aC|a

C→bA|aB|ε

图3-3习题3.5的DFA

(3)我们用一个非终结符A代表一个a(即有A→a),用一个非终结符B代表一个b(即有B→b);为了保证a和b的个数相同,则在出现一个a时应相应地出现一个B,出现一个b时则相应出现一个A。

假定已推导出bA,如果下一步要推导出连续两个b时,则应有bAbbAA。

也即为了保证b和A的个数一致,应有A→bAA;同理有B→aBB。

此外,为了保证递归地推出所要求的ab串,应有S→aBS和S→bAS。

由此得到无二义文法G[S]为

G[S]:

S→aBS|bAS|ε

A→bAA|a

B→aBB|b

3.6有文法G[S]:

S→aAcB|Bd

A→AaB|c

B→bScA|b

(1)试求句型aAaBcbbdcc和aAcbBdcc的句柄;

(2)写出句子acabcbbdcc的最左推导过程。

【解答】

(1)分别画出对应句型aAaBcbbdcc和aAcbBdcc的语法树如图3-4的(a)、(b)所示。

图3-4习题3.6的语法树

(a)aAaBcbbdcc;(b)aAcbBdcc

对树(a),直接短语有3个:

AaB、b和c,而AaB为最左直接短语(即为句柄)。

对树(b),直接短语有两个:

Bd和c,而Bd为最左直接短语。

能否不画出语法树,而直接由定义(即在句型中)寻找满足某个产生式的候选式这样一个最左子串(即句柄)呢?

例如,对句型aAaBcbbdcc,我们可以由左至右扫描找到第一个子串AaB,它恰好是满足A→AaB右部的子串;与树(a)对照,AaB的确是该句型的句柄。

是否这一方法始终正确呢?

我们继续检查句型aAcbBdcc,由左至右找到第一个子串c,这是满足A→C右部的子串,但由树(b)可知,c不是该句型的句柄。

由此可知,画出对应句型的语法树然后寻找最左直接短语是确定句柄的好方法。

(2)句子acabcbbdcc的最左推导如下:

SaAcBaAaBcBacaBcBacabcBacabcbScAacabcbBdcA

   acabcbbdcAacabcbbdcc

3.7对于文法G[S]:

S→(L)|aS|a

L→L,S|S

(1)画出句型(S,(a))的语法树;

(2)写出上述句型的所有短语、直接短语、句柄、素短语和最左素短语。

【解答】

(1)句型(S,(a))的语法树如图3-5所示。

图3-5句型(S,(a))的语法树

(2)由图3-5可知:

短语:

S、a、(a)、S,(a)、(S,(a));

直接短语:

a、S;

句柄:

S;

素短语:

素短语可由图3-5中相邻终结符之间的优先关系求得,即:

#⋖(⋖,⋖(⋖a⋗)⋗)⋗#

因此,素短语为a。

3.8下述文法描述了C语言整数变量的声明语句:

G[D]:

D→TL

T→int|long|short

L→id|L,id

(1)改造上述文法,使其接受相同的输入序列,但文法是右递归的;

(2)分别用上述文法G[D]和改造后的文法G[D′]为输入序列inta,b,c构造分析树。

【解答】

(1)消除左递归后,文法G[D′]如下:

D→TL

T→int|long|short

L→idL

图3-6两种文法为inta,b,c构造的分析树

(a)文法G(D);(b)文法G′(D)

3.9考虑文法G[S]:

S→(T)|a+S|a

T→T,S|S

消除文法的左递归及提取公共左因子,然后对每个非终结符写出不带回溯的递归子程序。

【解答】消除文法G[S]的左递归:

S→(T)|a+S|a

T→ST′

T′→,ST′|ε

提取公共左因子:

S→(T)|aS′

S′→+S|ε

T→ST′

T′→,ST′|ε

改造后的文法已经是LL

(1)文法,不带回溯的递归子程序如下:

voidmatch(tokent)

{

if(lookahead==t)

lookahead=nexttoken;

elseerror();

}

voidS()

{

if(lookahead==′a′)

match(′a′);

elseif(lookahead==′(′)

{

match(′(′);

T();

voidS′()

{

if(lookahead==′+′)

{

match(′+′);

S();

}

}

voidT()

{

S();

T′();

}

voidT′()

{

if(lookahead==′,′)

{

match(′,′);

S();

T′();

}

}

3.10已知文法G[A]:

A→aABl|a

B→Bb|d

(1)试给出与G[A]等价的LL

(1)文法G[A′];

(2)构造G[A′]的LL

(1)分析表;

(3)给出输入串aadl#的分析过程。

【解答】

(1)文法G[A]存在左递归和回溯,故其不是LL

(1)文法。

要将G[A]改造为LL

(1)文法,首先要消除文法的左递归,即将形如P→Pα|β的产生式改造为

P→βP′

P→αP′|ε

来消除左递归。

由此,将产生式B→Bb|d改造为

B→dB′

B′→bB′|ε

其次,应通过提取公共左因子的方法来消除G[A]中的回溯,即将产生式A→aABl|a改造为

A→aA′

A′→ABl|ε

最后得到改造后的文法为

G[A′]:

A→aA′

A′→ABl|ε

B→dB′

B′→bB′|ε

求得:

FIRST(A)={a}FIRST(A′)={a,ε}

FIRST(B)={d}FIRST(B′)={b,ε}

对文法开始符号A,有FOLLOW(A)={#}。

由A′→ABl得FIRST(B)\{ε}FOLLOW(A),即FOLLOW(A)={#,d};

由A′→ABl得FIRST(′l′)FOLLOW(B),即FOLLOW(B)={l};

由A→aA′得FOLLOW(A)FOLLOW(A′),即FOLLOW(A′)={#,d};

由B→dB′得FOLLOW(B)FOLLOW(B′),即FOLLOW(B′)={l}。

对A′→ABl来说,FIRST(A)∩FOLLOW(A′)={a}∩{#,d}=Φ,所以文法G′[A]为所求等价的LL

(1)文法。

(2)构造预测分析表的方法如下:

①对文法G[A′]的每个产生式A→α执行②、③步。

②对每个终结符a∈FIRST(A),把A→α加入到M[A,a]中,其中α为含有首字符a的候选式或为唯一的候选式。

③若ε∈FIRST(A),则对任何属于FOLLOW(A)的终结符b,将A→ε加入到M[A,b]中。

把所有无定义的M[A,a]标记上“出错”。

由此得到G[A′]的预测分析表,见表3-1。

表3-1预测分析表

(3)输入串aadl的分析过程见表3-2。

表3-2输入串aadl的分析过程

3.11将下述文法改造为LL

(1)文法:

G[V]:

V→N|N[E]

E→V|V+E

N→i

【解答】LL

(1)文法的基本条件是不含左递归和回溯(公共左因子),而文法G[V]中含有回溯,所以先消除回溯,得到文法G[V′]:

G[V′]:

V→NV′

V′→ε|[E]

E→VE′

E′→ε|+E

N→i

一个LL

(1)文法的充要条件是:

对每一个终结符A的任何两个不同产生式A→α|β有下面的条件成立:

(1)FIRST(α)∩FIRST(β)=Φ;

(2)假若βε,则有FIRST(α)∩FOLLOW(A)=Φ。

即求出G[V′]的FIRSTVT和LASTVT集如下:

FIRST(N)=FIRST(V)=FIRST(E)={i}

FIRST(V′)={[,ε}

FIRST(E′)={+,ε}

FOLLOW(V)={#}

由V′→…E]得FIRST(′)′)FOLLOW(E),即FOLLOW(E)={]};

由V→NV′得FIRST(V′)\{ε}FOLLOW(N),即FOLLOW(N)={[};

由E→VE′得FIRST(E′)\{ε}FOLLOW(V),即FOLLOW(V)={#,+};

由V→NV′得FOLLOW(V)FOLLOW(V′),即FOLLOW(V′)={#,+};

由V→NV′,且V′→ε得FOLLOW(V)FOLLOW(N),即FOLLOW(N)={[,#,+];

由E→VE′得FOLLOW(E)FOLLOW(E′),即FOLLOW(E′)={]};

则,对V′→ε|[E]有:

FIRST(ε)∩FIRST(′[′]=Φ;

对E′→ε|+E有:

FIRST(ε)∩FIRST(′+′)=Φ;

对V′→ε|[E]有:

FIRST(′[′)∩FOLLOW(V′)={[]∩{#,+}=Φ;

对E′→ε|+E有:

FIRST(′+′)∩FOLLOW(E′)={+}∩{}}=Φ。

故文法G[V′]为LL

(1)文法。

3.12对文法G[E]:

E→E+T|T

T→T*P|P

P→i

(1)构造该文法的优先关系表(不考虑语句括号#),并指出此文法是否为算符优先文法;

(2)构造文法G的优先函数。

【解答】FIRSTVT集构造方法:

①由P→a…或P→Qa…,则a∈FIRSTVT(P)。

②若a∈FIRSTVT(Q),且P→Q…,则a∈FIRSTVT(P),也即FIRSTVT(Q)FIRSTVT(P)。

由①得:

由E→E+…得FIRSTVT(E)={+};

由T→T*…得FIRSTVT(T)={*};

由P→i得FIRSTVT(P)={i}。

由②得:

由T→P得FIRSTVT(P)FIRSTVT(T),即FIRSTVT(T)={*,i};

由E→T得FIRSTVT(T)FIRSTVT(E),即FIRSTVT(T)={+,*,i}。

LASTVT集构造方法:

①由P→…a或P→…aQ,则a∈LASTVT(P)。

②若a∈LASTVT(Q),且P→…Q,则a∈LASTVT(P),也即LASTVT(Q)LASTVT(P)。

由①得:

E→…+T,得LASTVT(E)={+};

T→…*P,得LASTVT(T)={*};

P→i,得LASTVT(P)={i}。

由②得:

由T→P得LASTVT(P)LASTVT(T),即LASTVT(T)={*,i};

由E→T得LASTVT(T)LASTVT(E),即LASTVT(E)={+,*,i}。

优先关系表构造方法:

①对P→…ab…或P→…aQb…,有ab;

②对P→…aR…而b∈FIRSTVT(R),有a⋖b;

③对P→…Rb…而a∈LASTVT(R),有a⋗b。

解之无①。

由②得:

E→…+T,即+⋖FIRSTVT(T),有+⋖*,+⋖i;

  T→…*P,即*⋖FIRSTVT(P),有*i。

由③得:

E→E+…,即LASTVT(E)⋗+,有+⋗+,*⋗+,i⋗+;

T→T*…,即LASTVT(T)⋗*,有*⋗*,i⋗*。

得到优先关系表见表3-3。

由于该文法的任何产生式的右部都不含两个相继并列的非终结符,故属算符文法,且该文法中的任何终结符对(见优先关系表)至多满足、⋖和⋗三种关系之一,因而是算符优先文法。

表3-3习题3.12的优先关系表

用关系图构造优先函数的方法是:

对所有终结符a用有下脚标的fa、ga为结点名画出全部终结符所对应的结点。

若存在优先关系a⋗b或ab,则画一条从fa到ga的有向弧;若a⋖b或ab,则画一条从gb到fa的有向弧。

最后,对每个结点都赋一个数,此数等于从该结点出发所能到达的结点(包括出发结点)的个数,赋给fa的数作为f(a),赋给gb的数作为g(b)。

用关系图法构造本题的优先函数,如图3-7所示。

得到优先函数见表3-4。

表3-4习题3.12的优先函数表

图3-7习题3.12关系图构造

该优先函数表经检查与优先关系表没有矛盾,故为所求优先函数。

也可由定义直接构造优先函数,其方法是:

对每个终结符a,令f(a)=g(a)=1;如果a⋗b,而f(a)≤g(b),则令f(a)=g(b)+1;如果a⋖b,而f(a)≥g(b),则令g(b)=f(a)+1;如果ab,而f(a)≠g(b),则令min{f(a),g(b)}=max{f(a),g(b)}。

重复上述过程,直到每个终结符的函数值不再变化为止。

如果有一个函数值大于2n(n为终结符个数),则不存在优先函数。

优先函数的计算过程如表3-5所示。

表3-5优先函数的计算过程表

计算最终收敛,并且计算得出的优先函数与关系图构造得出的优先函数是一样的。

3.13设有文法G[S]:

S→a|b|(A)

A→SdA|S

(1)构造算符优先关系表;

(2)给出句型(SdSdS)的短语、简单短语、句柄、素短语和最左素短语;

(3)给出输入串(adb)#的分析过程。

【解答】

(1)先求文法G[S]的FIRSTVT集和LASTVT集:

由S→a|b|(A)得FIRSTVT(S)={a,b,(};

由A→Sd…得FIRSTVT(A)={d},又由A→S…得FIRSTVT(S)FIRSTVT(A),即FIRSTVT(A)={d,a,b,(};

由S→a|b|(A)得LASTVT(S)={a,b,)};

由A→…dA得LASTVT(A)={d},又由A→S得LASTVT(S)LASTVT(A),即LASTVT(A)={d,a,b,)}。

构造优先关系表方法如下:

①对P→…ab…或P→…aQb…,有ab;

②对P→…aR…而b∈FIRSTVT(R),有a⋖b;

③对P→…Rb…而a∈FIRSTVT(R),有a⋗b。

由此得到:

①由S→(A)得();

②由S→(A…得(⋖FIRSTVT(A),即(⋖d,(⋖a,(⋖b,(⋖(;

由A→…dA得d⋖FIRSTVT(A),即d⋖d,d⋖a,d⋖b,d⋖(;

③由S→…A)得LASTVT(A)⋗),即d⋗),a⋗),b⋗),)⋗);

由A→Sd…得LASTVT(S)⋗d,即a⋗d,b⋗d,)⋗d;

此外,由#S#得##;

由#⋖FIRSTVT(S)得#⋖a,#⋖b,#⋖(;

由LASTVT(S)⋗#得a⋗#,b⋗#,)⋗#。

最后得到算符优先关系表,见表3-6。

表3-6习题3.13的算符优先关系表

由表3-6可以看出,任何两个终结符之间至多只满足、⋖、⋗三种优先关系之一,故G[S]为算符优先文法。

(2)为求出句型(SdSdS)的短语、简单短语、句柄,我们先画出该句型对应的语法树,如图3-8所示。

图3-8句型(SdSdS)的语法树

由图3-8得到:

短语:

S,SdS,SdSdS,(SdSdS)注意,句型中的素短语具有如下形式:

aj-1⋖ajaj+1…ai⋗ai+1

而最左素短语就是该句型中所找到的最左边的那个素短语,即最左素短语必须具备三个条件:

①至少包含一个终结符(是否包含非终结符则按短语的要求确定);

②除自身外不得包含其他素短语(最小性);

③在句型中具有最左性。

图3-9句型(SdSdS)的优先关系

简单短语(即直接短语):

S

句柄(即最左直接短语):

S

可以通过分析图3-8的语法树来求素短语和最左素短语,即找出语法树中的所有相邻终结符(中间可有一个非终结符)之间的优先关系。

确定优先关系的原则是:

①同层的优先关系为;

②不同层时,层次离树根远者优先级高,层次离树根近者优先级低(恰好验证了优先关系表的构造算法);

③在句型ω两侧加上语句括号“#”,即#ω#,则有#⋖ω和ω⋗#,由此我们得到句型(SdSdS)的优先关系如图3-9所示。

因此,由图3-9得到SdS为句型(SdSdS)的素短语,它同时也是该句型的最左素短语。

(3)输入串(adb)#的分析过程见表3-7。

表3-7输入串(adb)#的分析过程

为便于分析,同时给出了(adb)#的语法树,如图3-10所示。

图3-10(adb)的语法树

3.14在算符优先分析法中,为什么要在找到最左素短语的尾时才返回来确定其对应的头,能否按扫描顺序先找到头后再找到对应的尾,为什么?

【解答】设句型的一般形式为N1a1N2a2…NnanNn+1。

其中,每个ai都是终结符,而Ni则是可有可无的非终结符。

对上述句型可以找出该句型中的所有素短语,每个素短语都具有如下形式:

…aj-1⋖ajaj+1…ai⋗ai+1…

如果某句型得到的优先关系如下:

…⋖…⋖……⋗…⋗

则当从左至右扫描到第一个“⋗”时,再由此从右至左扫描到第一个“⋖”时,它们之间(当然不包含第一个“⋖”前一个终结符和第二个“⋗”后一个终结符)即为最左素短语。

如果由左至右扫描到第一个“⋖”,可以看出这并不一定是最左素短语的开头,因为由它开始并不一定是素短语(在其内部还可能包含其他更小的素短语),所以,在算符优先分析算法中,只有先找到最左素短语的尾(即“⋗”),才返回来确定与其对应的头(即“⋖”);而不能按扫描顺序先找到头然后再找到对应的尾。

3.15试证明在算符文法中,任何句型都不包含两个相邻的非终结符。

【解答】设文法G=(VT,VN,S,ξ),其中VT是终结符集;VN是非终结符集;ξ为产生式集合;S是开始符号。

对句型的推导长度n作如下归纳:

(1)当n=1时,S⇒α,则存在一条产生式S→α属于ε,其中a∈(VT∪VN)*。

由于文法是算符文法,所以α中没有两个相邻非终结符,故归纳初始成立。

(2)设n=k时结论成立,则对任何k+1步推导所产生的句型必为

Sα∪β⇒α∨β

其中,α、β∈(VT∪VN)*,U∈VN,而U→V是一条产生式。

由归纳假设,U是非终结符,设α=α1α2…αn,β=β1β2…βm,其中αi、βj∈(VT∪VN)(1≤i≤n-1,2≤j≤m);但αn和βm必为位于U两侧的终结符。

设V=V1V2…Vr,由于它是算符文法的一个产生式右部候选式,因此V1V2…Vr中不会有相邻的非终结符出现。

又因为αnV1和Vrβ1中的αn、β1为终结符,也即在推导长度为k+1时所产生的句型

α1α2…αnV1V2…Vrβ1β2…βm

不会出现相邻的非终结符,故n=k+1时结论成立。

显然,在α或β为空时结论也成立。

3.16给出文法G[S]:

S→aSb∣P

P→bPc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 金融投资

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1