编译原理作业集第四章修订版
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第四章语法分析—自上而下分析
本章要点
1. 语法分析器的功能;
2. 自上而下分析方法,LL(1)文法
3. 递归下降分析程序构造;
4. 预测分析表的构造及预测分析过程;
5. LL(1)分析中的错误处理。
本章目标
理解和掌握语法分析器的功能、自上而下分析所面临的问题、LL(1)分析法、递归下降分析的构造过程、预测分析程序等内容。
本章重点
1.语法分析器的功能,自上而下的基本概念
2.LL(1)文法的条件及其判别,计算first集和follow集
3.递归下降分析方法、预测分析表的构造及其预测过程。
本章难点
1. 非终结符的First集合,产生式候选的First集合,非终结符的follow集合的求解;
2. 左递归消除;
3. 递归下降分析程序的编写;
作业题
一、单项选择题:
1. 高级语言编译程序常用的语法分析方法中,递归下降分析法属于分析法。
a. 自左至右
b. 自顶向下
c. 自底向上
d. 自右向左 2. 上下文无关文法可以用 来描述。
a. 正则表达式
b. 正规文法
c. 扩展的BNF
d. 翻译模式 3. 自上而下分析面临的四个问题中,不包括
a. 需消除左递归;
b. 存在回朔;
c. 虚假匹配;
d. 寻找可归约串
4. 语法分析器接收以________为单位的输入,并产生有关信息供以后各阶段使用。
a. 表达式;
b. 产生式;
c. 单词;
d. 语句;
5. 自上而下分析的主旨是,对任何单词符号串,试图用一切可能的办法,从文法开始符号(根结点)出发,________。
a. 为输入串寻找最右推导;
b. 为输入串寻找最左直接子树;
c. 为输入串建立最右直接子树;
d. 为输入串寻找最左推导;
6. 把规则T→F | T*F 表示成扩展的巴克斯范式以后,画出它的语法图应该是 。
图a
图b
图c
图d
7. 下列文法中,_______是LL(1)文法。
a. S →aSb|ab
b. S →ab|Sab
c. S →aS|b
d. S →aS|a 8. 设有文法G : S→Ap|Bq A→a|cA
B→b|dB
则,First(Ap)={_______________} a. a,c b. b,d c. p, q d. A, p
一.答案:1. b ;2. c ;3. d ;4. c ;5. d ;6. 图a ;
二、填空题:
1. 语法分析器的工作本质上就是按____________________,识别输入符号串是否为一个句
子。
这里所说的输入串是指由____________________组成的有限序列。
2. 自顶向下分析会遇到的主要问题是____________________和__________________。
3. 自上而下地为输入串建立一棵语法树,就是为输入串寻找一个______________。
4. 在扩充的巴科斯范式中,用______________表示符号或串α的出现可有可无。
5. 对于一个文法,当给出一串符号时,怎么能知道它是不是该文法的一个句子呢?这就要判断,看是否能。
6. 文法exp → exp addop term | term 消除左递归的结果为。
7. 写出E→T | E+T的EBNF范式为。
8. 扩展的巴克斯范式描述语法的好处是,直观易懂,便于表示。
二.答案:1. 文法的产生式,单词符号(文法的终结符)2. 左递归,回溯;3.最左推导;
4. 方括号(或[α]);
5. 从文法的开始符号出发推导出这个输入串。
(或:能否建立一棵与输入串相匹配的语法分析树。
)
6. exp → term exp′;exp′→ addop term exp′| ε;
7. E→T{+T};
8. 左递归消去和左因子提取。
三、判断题:
1. LL(k)文法都不是二义性的。
()
2. 存在一种算法,能判定任何上下文无关文法是否是LL(1)的。
( )
3. 一个文法是含有左递归的,如果存在非终结符P,使得P⇒*αP。
()
4. 提取公共左因子的副产品是引进了大量的非终结符和ε产生式。
( )
5. 把一个文法改造成任何非终结符的所有后选终结首符集两两不相交的办法是消除左递归。
( )
6. 若X∈V T,则FIRST(X)={ X }。
( )
7. 一个文法的预测分析表含有多重定义入口,说明该文法是LL(1)的。
()
8. 自上而下分析及自下而上分析中的“下”是指被分析的源程序串。
()
三.答案:1. √;2. √;3. ×;4. √;5. ×;6. √;7. ×;8. √;
四、名词解释:
1. 左递归;
2. 递归下降分析器;
3. LL(1)文法;
4. 预测分析表
5. 自上而下分析
四.答案:
1.一个文法如果存在非终结符P,P=>+Pα,则称该文法是左递归的。
2. 当一个文法满足LL(1)条件时,可以为它构造一个不带回溯的的自上而下分析程序,该程序是由一组递归过程组成的,每个过程对应文法的一个非终结符。
这样的分析程序称为递归
下降分析器。
3. 一个文法G,如果满足以下条件,则称为LL(1)文法:
(1)文法不含左递归;
(2)对于文法中每一个非终结符A的各个产生式的候选首符集两两不相交;
(3)对文法中的每个非终结符A,若它存在某个候选首符集包含ε,则A的First集合和Follow 集合的交集为空。
4. 预测分析表是一个M[A, a]形式的矩阵。
其中A为非终结符,a是终结符或“#”。
矩阵元素M[A, a]中存放着一条关于A的产生式,指出当A面临输入符号a时所应采取的候选。
M[A, a]中也可能存放一个“出错标志”,指出A根本不该面临输入符号a。
5. 自上而下分析是,对任何输入串,试图用一切可能的办法,从文法开始符号(根结点)出发,自上而下地为输入串建立一棵语法树。
或者说,为输入串寻找一个最左推导。
五、简答题:
1. 词法分析和语法分析都是对字符串进行识别的,二者有何区别?
2. 试说明没有一个左递归文法是LL(1)的。
3. 试说明没有一个LL(1)文法是二义性的。
4. 为什么要消除回溯?
5. 为什么要提取左因子?
6. 下面文法是有左递归吗?若有,提取左递归。
Declist→Declist; Decl | Decl
Decl→idList:Type
IdList→Idlist, id | id
Type→ScalarType | array (ScalarTypeList) of Type
ScalarType→id | Bound..Bound
Bound→Sign IntLiteral | id
Sign→+ | - | e
ScalarTypeList→ScalarTypeList, ScalarType | ScalarType
五.答案:
1. 答:词法分析的输入符号串是一个单词,而语法分析的输入符号串是一个句子。
词法分析的一个输入符号串是由单个符号组成的单词;语法分析的输入符号串是由词法分析得来的单词组成的句子。
2. 对于任一个左递归文法来说,存在一个A∈V N,有A A...,因此,在文法中必有如下的
规则序列:
A → A1...
A1 → A2...
.....................
An→ Aα|β
Aαβ。
显然,FIRST(Aα)∩FIRST(β)≠Φ。
因此,没有一个左递归文法是LL(1)的。
3. 解:
设有一个LL(1)文法G是二义性的,那么,一定存在一个W∈L(G),W=a1, a2......, a n,有两棵不同的分析树。
如果按最左推导构造这两棵分析树,按么,一定有两个最左推导序列,这来年改革最左推导序列的不同在于,于对某一个A∈V N和当前要匹配的a i(1≤i≤n),分别使用A的两个不同的候选式A→α和A→β进行推导以匹配a i
(i) 若αε且βε,则必有
a i∈FIRST(α)且a i∈FIRST(β),FIRST(α)∩FIRST(β)≠Φ
(ii) 若α和β有一个能推导出ε,比如βε,则
a i∈FIRST(α)且a i∈FOLLOW(A)显然,FIRST(α)∩FOLLOW(A)≠Φ
无论(i)还是(ii),都和G是LL(1)文法矛盾。
4. 假定当前轮到非终结符A去执行匹配任务,A共有n个候选α1、α2、……αn,这时候该用哪一个候选去替换A,原始的办法是采用对所有候选采取“试探”的方法。
如果某个候选不成功就需要“回退”。
这个回退的过程会导致前次匹配的许多工作推到重来,效率低。
而且,最终匹配不成功的时候,难以直到输入串中出错的确切位置。
5. 假定当前轮到非终结符A去执行匹配任务,A共有n个候选α1、α2、……αn,即A→α1|α2|……|αn。
A面临的第一个输入符号为a,如果a属于某个First(αi),则用该αi来匹配A。
但是,若a既属于某个First(αi),又属于某个First(αj),则说明αi和αi存在共同的左部,也就是说,有共同的左因子。
此时无法确定到底是用αi还是用αj来匹配A。
所以要消除左因子。
六、应用题
1. 已知文法G[S]:
S → (L) | a
L → L,S | S
ⅰ.消除左递归,若有左因子则提取之;
ⅱ.对(1)中得到的文法求First集合和Follow集合
ⅲ.对(1)中得到的文法构造一个预测分析表;
ⅳ.给出对句子(a,(a,a))上的分析动作
1.答案:将所给文法消除左递归得G′:
S → (L) | a
L → SL′
L′→ ,SL′ |ε
实现预测分析器的不含递归调用的一种有效方法是使用一张分析表和一个栈进行联合控制,下面构造预测分析表:
根据文法G′有
FIRST(S) = { ( , a } FOLLOW(S) = {#, ) , ′,′}
FIRST(L) = { ( , a } FOLLOW(S) = { ) }
FIRST(L′) = {′,′, ε} FOLLOW(L′) = { ) }
2. 考查文法G(s):
S→( T ) | a + S | a
T→T, S | S
ⅰ. 消除文法的左递归,提取公共左因子
ⅱ. 改造后的文法是LL(1)的吗?为什么?
ⅲ. 如果是LL(1)文法,对每个非终结符,写出不带回朔的递归子程序。
2.答案:
ⅰ.消除文法的左递归G ( s ):
S→ ( T ) | a + S | a
T→ S T′
T`→ , S T′| ε
再提取公共左因子,最后得到改造后的文法G[S]:
①S→( T ) | a S′
②S′→ + S | ε
③T→ S T′
④T′→, S T′ | ε
ⅱ.
First(S)={(,a };Follow(S)={#,‘,’};First(S’)={+,ε};Follow(S’)= {#,‘,’};First(T)={(,a };Follow(T)={ ) };
First(T’)={‘,’ ,ε}; Follow(T’) ={ ) };
产生式①的两个候选的First集合:
Fist((T))={(},First(aS’)={a}
不相交,满足条件。
产生式②,First(S’)∩Follow(S’)=Φ;
产生式④,First(T’)∩Follow(T’)=Φ;
所以,改造后的文法是LL(1)的,
ⅲ.
我们构造不带回溯的递归子程序如下:
①S→( T ) | a S′
PROCEDURE S;
DEGIN
IF SYM=′( ′THEN
BEGIN
ADV ANCE
T;
IF SYM=′ ) ′THEN ADV ANCE
ELSE ERROR
END
ELSE IF SYM=′a′ THEN
BEGIN
ADV ANCE;
END
ELSE ERROR
END;
②S′→ + S | ε
PROCEDURE S′;
BEGIN
IF SYM=′ + ′THEN BEGIN ADV ANCE;S END END;
③T→ S T′
PROCEDURE T;
BEGIIN
S; T ′
END;
④T′→, S T′ | ε
PROCEDURE T′;
BEGIN
IF SYM=′ , ′ THEN
BEGIN
ADVANCE;
S; T′
END
END;
3. 已知文法G[S]:
S → uBDz
B → Br | w
D → EF
E → y | ε
F → x | ε
(a) 求每个非终结符的FIRST和Follow集。
(b) 构造这个文法的LL(1)分析表
(c) 说明这个文法不是LL(1)的;
(d) 尽可能少地修改此文法,使其成为能产生相同语言的LL(1)文法.
3. 答案:
(a) FIRST(S) = { u } FOLLOW(S) = {#}
FIRST(B) = {w } FOLLOW(B) = { r, z }
FIRST(D) = { x, y, ε} FOLLOW(D) = { z }
FIRST(E) = { y, ε} FOLLOW(E) = { x, z }
FIRST(F) = { x, ε } FOLLOW(F) = { z }
(b) 该文法的LL(1)分析表为:
(c) 因为M[B, w]有两个产生式B→Bv, B→w
且FIRST(Bv)=FIRST(w) = { w }
所以不是LL(1)的。
(d) 消除左递归即可。
S→uBDz
B→wB′
B′→rB′ | ε
D → EF
E = y | ε
F = x | ε
4. 已知文法如下:
E→T | E+T T→F | T*F F→i | (E)
构造预测分析表,并给出对输入串i*i+i的分析过程。
4.答案:
首先消除左递归,得到新文法如下:
E→TE′
E′→+TE′|ε
T→FT′
T′→*FT′|ε
F→(E)|i
对每个非终结符构造First和Follow集合:
FIRST(E) = FIRST(T) = FIRST(F) = { ( , i };FIRST(E′) = { + , ε};FIRST(T′) = { * , ε} FOLLOW(E) = FOLLOW(E′) = { ) , # };FOLLOW(T) = FOLLOW(T′) = { + ,) ,# } FOLLOW(F) = { * , + , ) , # }
再通过对文法的每个非终结符的任意候选都构造出First集合:
FIRST(TE′)= {(,i};FIRST(+TE′)={+} ;FIRST(FT′)={(,i};FIRST(*FT′)={*};FIRST((E))={(}
得到预测分析表如下:
对输入串的分析过程如下:
5. 文法G1:
S→a|^|(T)
T→T,S|S
(1) 证明文法G是LL(1)文法。
(2) 构造LL(1)分析表。
(3) 写出句子(a,a)#的分析过程。
5. 答案:
(1)先消除左递归,得到文法G2:
0) S→a
1) S→^
2) S→( T )
3) T→S N2
4) N2→, S N2
5) N2→ε
求非终结符的First和Follow集合:
FIRST FOLLOW S { a,^,( } { #,,,) } T { a,^,( } { ) }
N2 { ,,ε } { ) }
对左部为N2的产生式可知:
FIRST (, S N2)={,}
FIRST (ε)={ε}
FIRST(, S N2) ∩ FIRST(ε)=∅;
且:FIRST(N2) ∩ FOLLOW(N2)= ∅所以文法是LL(1)的。
得到预测分析表:
a ^ ( ) , #
S S→a S→^S→( T )
T T→SN2T→SN2T→SN2
N2 N2→εN2→,SN2
也可由预测分析表中无多重入口判定文法是LL(1)的。
对输入串(a,a)#的分析过程为:
可见输入串(a,a)#是文法的句子。
6. 设文法G(S):
S→(L)|aS|a L→L,S|S
(1)消除左递归和提取左因子;
(2)计算每个非终结符的FIRST和FOLLOW;
(3)构造预测分析表。
(4)已知输入串(aa,a)a,该输入串是否文法的句子?给出分析过程。
7. 对于文法
bexpr → bexpr or bterm | bterm
bterm → bterm and bfactor | bfactor
bfactor→ not bfactor | (bexpr) | true | false
构造一个预测分析器(表)。
答案:
消除左递归和提取左因子
bexpr → bterm bexpr′
bexpr′→ or bterm bexpr′ | ε
bterm → bfactor b term′
bterm′→ and bfactor bterm′ | ε
bfactor→ not bfactor | (bexpr) | true | false
First(bexpr)=First(bterm)=First(bfactor)={ not, (, true,false } First(bexpr′)={ or , ε }
First(bterm′)={ and, ε }
Follow(bexpr)=Follow(bexpr′)={ ) , $ }
Follow(bterm)=Follow(bterm′)={or , ) , $}
Follow(bfactor)={and , or, ) , $}
8. 已知G[R]的产生式如下:
R → R′ | ′T | T
T → TF | F
F → F* | C
C → (R) | a | b
构造它的LL(1)分析表,并写出对输入串a|ba*的分析过程。
答案:
①消除上面文法中的左递归
R → TR′
R′ → ′|′ TR′ | ε
T → FT′
T′ → FT′ | ε
F → CF′
F → *F′| ε
C → (R) | a | b
②计算FIRST(α)和FOLLOW(A)
③构造LL(1)分析表。
9. 已知文法如下:
S→S*T | S/T | T
T→T+F | T-F | F
F →(S) | i | i e i
构造预测分析表,并给出对输入串i/i*i+i的分析过程。
10. 已知文法:
S→Ac|c
A→Bb|b
B→Sa|a
构造预测分析表,给出对输入串cabc的分析过程。
11. 已知文法G:
S → ( L | a
L → S , L | )
(1)构造文法G 的预测分析表。
(2)若输入串为“(a,)”,请给出语法分析过程。
解(1)
1)求各非终结符的FISRT 集和FOLLOW 集:FIRST(S) = { (, a )
FIRST(L) = { a } FIRST(S) = { (, ), a }
FOLLOW(S) = { ′,′, # }
FOLLOW(L) = FOLLOW(S) ={ ′,′, # }
2
( a , } #
S S→ ( L S→ a
L L→ S , L L→ S , L L → )
1所示。
表1 对输入串“(a,)”的分析过程
步骤分析栈输入串所用产生式
0#S(a,)#
1#L( (a,)#S → ( L
12. 给定文法
G=({ i,d,′(′,′)′ },{E,A},E,P)
其中P:
E →iA
E →EA
A → i
A →d
A → (E)
(1)消除左递归;
(2)计算改写后文法中各非终结符的FIRST 集和FOLLOW 集;
(3)构造改写后文法的预测分析表;该文法是LL(1) 文法吗?。
解
(1)消除左递归后的文法为:
E → iA E′
E′→ ε | AE′
A → i
A →d
A → ( E )
(2)各非终结符的FISRT集和FOLLOW集
FIRST( E ) ={i}
FIRST(E′) = {i, d, (, ε)
FIRST( A ) ={i, d, ()
FOLLOW( E ) ={), # }
FOLLOW(E′) ={ }, # }
FOLLOW( A ) ={i, d, (, ), # }
(3)改写后文法的预测分析表:
预测分析表中无多重入口,因此该文法是LL(1) 文法.
13. 已知文法:
A→aABe|a
B→Bb|d
ⅰ.消除左递归,若有左因子则提取之;
ⅱ.对(1)中得到的文法求First集合和Follow集合
ⅲ.对(1)中得到的文法构造一个预测分析表;
ⅳ.给出对句子aadb上的分析动作
答案:
改写文法为:
0) A→a N3
1) N3→A B e
2) N3→ε
3) B→d N2
4) N2→b N2
5) N2→ε
Predicting Analysis Table
由预测分析表中无多重入口判定文法是LL(1)的。
14. 已知文法:
S→Aa|b
A→SB
B→ab
(1) 改写文法以消除左递归,若有左因子则提取之;
(2)计算改写后文法中各非终结符的FIRST 集和FOLLOW 集;
(3)构造改写后文法的预测分析表;该文法是LL(1) 文法吗?。
答案:
第1种改写:
S→SBa|b
B→ab
0) S→b N2
1) N2→B a N2
2) N2→ε
由预测分析表中无多重入口判定文法是LL(1)的。
第2种改写:
S→Aa|b
A→AaB|bB
B→ab
0) S→A a
1) S→b
2) A→b B N3
3) N3→a B N3
4) N3→ε
由预测分析表中含有多重入口判定文法不是LL(1)的。
15. 文法:
S→MH|a
H→LSo|ε
K→dML|ε
L→eHf
M→K|bLM
(1)消除左递归;
(2)计算改写后文法中各非终结符的FIRST 集和FOLLOW 集;
(3)构造改写后文法的预测分析表;该文法是LL(1) 文法吗?。
答案:
展开为:
0)S→M H
1)S→a
2)H→L S o
3)H→ε
4)K→d M L
5)K→ε
6)L→e H f
7)M→K
由预测分析表中无多重入口判定文法是LL(1)的。
16. 对下面文法
Expr→-Expr
Expr→(Expr)|Var ExprTail
ExprTail→-Expr |
Var→id VarTail
VarTail→(Expr) |
(1) 构造LL(1)分析表。
(2) 给出对句子id--id((id))的分析过程。
17. 考查文法G(s):
S→( T ) | a + S | a
T→T, S | S
ⅰ. 消除文法的左递归,提取公共左因子
ⅱ. 改造后的文法是LL(1)的吗?为什么?
ⅲ. 如果是LL(1)文法,对输入串a+(a,a)写出分析过程。