1.First集、Follow集
E→TE’ E’→+TE’ E’→ε T→FT’ T’→*FT’ T’→ε F→(E)|i
求文法中非终结符号以及符号串的FIRST集、Follow集。
开始完成First集
First | Follow | |
E | ||
E' | ||
T | ||
T' | ||
F |
1. E→TE’ 可得:First(E) = First(T) ,First(T)未知,先跳过
2. E’→+TE’ 和 E’→ε 可得:First(E') = +,ε
First | Follow | |
E | ||
E' | +,ε | |
T | ||
T' | ||
F |
3. T→FT’ 可得 First(T) = First(F),First(F)未知,先跳过
4. T’→*FT’和 T’→ε 可得 First(T') = *,ε
First | Follow | |
E | ||
E' | +,ε | |
T | ||
T' | *,ε | |
F |
5. F→(E)|i 可得 First(F) = (,i
First | Follow | |
E | ||
E' | +,ε | |
T | ||
T' | *,ε | |
F | (,i |
第一遍结束,开始第二遍
1. E→TE’ 可得:First(E) = First(T),,First(T)未知,先跳过
2. T→FT’ 可得 First(T) = First(F) , First(F) = (,i ,故:
First | Follow | |
E | ||
E' | +,ε | |
T | (,i | |
T' | *,ε | |
F | (,i |
第二遍结束,开始第三遍:
3. E→TE’ 可得:First(E) = First(T),,First(T)=(,i 故:
First | Follow | |
E | (,i | |
E' | +,ε | |
T | (,i | |
T' | *,ε | |
F | (,i |
完成First集
开始完成Follow集
1. 先将#加入到Follow(E)中
First | Follow | |
E | (,i | # |
E' | +,ε | |
T | (,i | |
T' | *,ε | |
F | (,i |
2.E→TE’ ,可得:Follow(E)要加入到Follow(T)和Follow(E')
First | Follow | |
E | (,i | # |
E' | +,ε | # |
T | (,i | # |
T' | *,ε | |
F | (,i |
First(E′)中非ε 元素可以加入到Follow(T)中
First | Follow | |
E | (,i | # |
E' | +,ε | # |
T | (,i | #,+ |
T' | *,ε | |
F | (,i |
3.E’→+TE’ | ε , 可得,Follow(E')可加入到Follow(T),无变化
4.T→FT’ , 可得,Follow(T)可加入到Follow(F),Follow(T')
First | Follow | |
E | (,i | # |
E' | +,ε | # |
T | (,i | #,+ |
T' | *,ε | #,+ |
F | (,i | #,+ |
First(T')可加入到Follow(F)
First | Follow | |
E | (,i | # |
E' | +,ε | # |
T | (,i | #,+ |
T' | *,ε | #,+ |
F | (,i | #,+,* |
5. T’→*FT’ | ε , 可得,Follow(T')可加入到Follow(F),无变化
First(T')可加入到Follow(F),无变化
6.F→(E)|i , 可得, 终结符 )可加入到E的Follow集
First | Follow | |
E | (,i | #,) |
E' | +,ε | # |
T | (,i | #,+ |
T' | *,ε | #,+ |
F | (,i | #,+,* |
第二遍查看
1.E→TE’ , 可得,将Follow(E)加入到Follow(T),Follow(E'),
First | Follow | |
E | (,i | #,) |
E' | +,ε | #,) |
T | (,i | #,+,) |
T' | *,ε | #,+ |
F | (,i | #,+,* |
2.E’→+TE’ | ε , 可得,Follow(E')可加入到Follow(T),无变化
3.T→FT’ , 可得,Follow(T)可加入到Follow(F),Follow(T')
First | Follow | |
E | (,i | #,) |
E' | +,ε | #,) |
T | (,i | #,+,) |
T' | *,ε | #,+,) |
F | (,i | #,+,*,) |
4.T’→*FT’ | ε , 可得,Follow(T')可加入到Follow(F),无变化
First(T')可加入到Follow(F),无变化
5.F→(E)|i , 无变化。
因此得到最终答案:
First | Follow | |
E | (,i | #,) |
E' | +,ε | #,) |
T | (,i | #,+,) |
T' | *,ε | #,+,) |
F | (,i | #,+,*,) |
2.根据First和Follow求LL(1)分析表
E→TE’
E’→+TE’
E’→ε
T→FT’
T’→*FT’
T’→ε
F→(E)|i
i | + | * | ( | ) | # | |
E | E遇到i,i在First(E)中,E只有一个候选式 填入:E→TE’ | E→TE’ | ||||
E' | E’→+TE’ | First(E')中含有ε,故E’遇到Follow(E')中的终结符时均填入E′→ε | First(E')中含有ε,故E’遇到Follow(E')中的终结符时均填入E′→ε | |||
T | T→FT’ | T→FT’ | ||||
T' | T’→ε | T’→*FT’ | T’→ε | T’→ε | ||
F | F→i | F→(E) |
即:
根据LL(1)分析表,进行LL(1)分析
例:对i+i*i进行分析
表中输出的产生式序列构成对输入符号串的最左推导。
按此产生式序列构造输入符号串i+i*i的最左推导过程如下
![](https://img-blog.csdnimg.cn/ff4bfdb6f043400389490f2718c2e458.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAWnVja0Q=,size_20,color_FFFFFF,t_70,g_se,x_16)
3.递归下降分析
1.递归下降分析
考虑文法Z::=(U)|aUb,U::=dZ|e,为其构造递归下降分析子程序。并对输入串aeb进行语法分析
推导过程:Z=>aUb=>aeb
2.递归下降分析存在的问题
问题 | 描述 | 解释 | 解决 |
---|---|---|---|
左递归 | E→E+T | 等价文法 | |
局部二义性 | A→ab\|a | 右部多个第一个符号相同 | 提取公因子、加入新的非终结符号 |
右部第一个符号是非终结符 | A→α\|β | α和β都是非终结符,都能继续推导 |
左递归问题
1.直接左递归
2.间接左递归(首先要变成直接左递归)
消除局部二义性问题,右部第一个符号是非终结符
首先要求出每个侯选式的首符号集
1.FIRST(α)∩FIRST(β)=φ,各个候选式的First集两两不相交。
2.若ε ∈ FIRST(β),那么,FIRST(α)∩FOLLOW(U)=φ
求出首符号集后,若满足上述两条件,那么对于规则U∷=α|β,可以根据下列规则来选择侯选式: 设当前的输入符号是a ,a∈Vt
1.若a∈FIRST(α) 或ε∈FIRST(α)且a∈FOLLOW(U),则用α侯选式。
2.若a∈FIRST(β) 或ε∈FIRST(β)且a∈FOLLOW(U),则用β侯选式。
3.若a∈FIRST(α) 且a∈FIRST(β) ,则语法错,转出错处理。
要实现没有回溯(确定)的自顶向下分析,文法必须满足两个条件(但还不一定能够保证是没有回溯的):
1.文法是非左递归的。
2.对文法的任一非终结符号,若其规则右部有多项选择,那么各选项所推出的终结符号串的头符号集合要两两不相交
LL(1)文法分析
我们把能由某一LL(1)文法产生的语言称为LL(1)语言。
LL(1)文法具有下列性质:
1)任何LL(1)文法都是无二义的。
2)若文法中有左递归,肯定不是LL(1)文法。但有些左递归文法可转换成右递归文法,从而满足LL(1)文法的要求。
3)存在一种算法,能判定文法是否为LL(1)文法。
4)存在一种算法,能判定任意两个LL(1)文法是否产生相同的语言。
5)不存在这样的算法,判定任意上下文无关语言能否由LL(1)文法产生
6)非LL(1)语言是存在的。 在LL系列分析方法中,若每一步推导不是向前看一个字符,而是看K个字符才能确定要选用的产生式,则称为LL(K)分析,能满足LL(K)分析条件的文法叫LL(K)文法。
LL1(1)文法分析存在的主要问题
1.不能处理左递归文法
需要转换成等价的右递归规则
形如:U::=x|y|…|z|Uv
转换成:U::= (x|y|….|z )U’
U’::=vU’
U’::=ε
例如:E→E+T|T ,其等价的右递归规则是 E→TE’,E’→+TE’|ε
2.分析表多重定义
若一个LL(1)文法的分析表不出现多重定义,当且仅当对于文法G的每个非终结符A的任何两条不同规则A→α|β ,下面条件成立:
FIRST(α)∩FIRST(β)=φ 即头符号集不相交。
假若β==*>ε,那么,FIRST(α)∩FOLLOW(A)=φ,即α所能推出的符号串的头符号集中的元素不能出现在FOLLOW(A)中。
例如,规则:T→(E)|a(E)|a 可改成:T→(E)|aT’,T’→(E)|ε
如果出现了相交的情况,那么分析表必然有多重定义。这个问题有时可通过提取公因子,增加新的非终结符号来解决(见递归下降的问题解决方法)。
但并非所有的文法都可用此法解决分析表的多重定义。
考虑有文法G[S]:S→AU|BR , A→aAU|b , B→aBR|b , U→c , R→d
对于规则S→AU|BR,因为FIRST(AU)∩FIRST(BR)≠φ,故该文法不是LL(1)文法。
为了能够提取公因子,必须将非终结符号A、B的产生式带入S的产生式中,得到:
S→aAUU|bU|aBRR|bR
经提取公因子后,得到S→a(AUU|BRR)|b(U|R),令S’、S”分别代替括号中的左右部分,得如下等价文法:
S→aS’|bS” , S’→AUU|BRR , S”→U|R , A→aAU|b , B→aBR|b , U→c ,R→d
显然,对于规则S’→AUU|BRR,因为FIRST(AUU)∩FIRST(BRR)≠φ,故它仍然不是LL(1)文法。且无论重复多少次提取公因子,都不能把它变成LL(1)文法。由于递归下降分析法也存在这类问题,所以,自顶向下分析方法无法对这类文法进行语法分析。
习题
4.4 有文法G[A]:A::=aABe|ε B::=Bb|b
1)求每个非终结符号的FOLLOW集。
2)该文法是LL(1)文法吗?
3)构造LL(1)分析表。
4.5 若有文法A→(A)A|ε,
1)为非终结符A构造First集合和Follow集合。
2)说明该文法是LL(1)的文法。
LR(0)
构建LR(0)步骤:
1.改造文法
2.写出所有项目
3.构建项目规范簇
4.构造项目规范簇DFA
5.写出ACTION 和GOTO (LR(0)分析表)
例题:
给出文法:
G[S] : S->BB
B->aB|b
即:
S->BB
B->aB
B->b
一、改造文法
S' -> S
S->BB
B->aB
B->b
二、所有项目
三、构建项目规范簇
以下用 cl() 来代表 closure() 闭包符号,方便表示,实际要写全
四.构造项目规范簇DFA
根据上面的GOTO,即可画出如下图。GOTO(I0,S) = I1 表示 I0接收S到I1
五、写出ACTION 和GOTO (LR(0)分析表)
过程如下:
习题:
5.1 考虑以下的文法:
S → S;T | T
T → a
1)为这个文法构造L R ( 0 )的项目集规范族。
2)这个文法是不是L R ( 0 )文法?如果是,则构造L R ( 0 )分析表。
3)对输入串a;a进行分析。
对输入串a;a进行分析。
LR0中的一些问题
1.拓广文法
对于第一步改造文法,书中给过这样一个例子:
拓广结果如下:
表示,我们引入了一个符号S,使得文法的开始符号所在的规则唯一。
因此我们上面举的S->BB 这个例子,需要拓广的原因就是,S所在的规则不唯一。因此需要引入S'->S
练习
对该文法构造LR(0)分析表
分析表: