这学期开始学习编译原理,学了4章,对于书本有了一些新的理解,这里我会写下我的理解,这也会帮助你的理解,反正书上面的我是看不懂呀555
这里我直接写第四章节的,前面的后面再补充。
本章主要内容只有如下几个部分,文章虽然乱,但是绝对对你帮助巨大,相信我兄der们:
我主要写消除左递归、提取左因子、LL(1)文法理解、构造及判断,FIRST和FOLLOW集合的求解方法,和预测分析表的构建。
首先感谢博主小落0117的文章,帮助加深了我的理解。
消除左递归,挑干活来说
这是书上的公式,其实所有的题都可以按这个公式消除左递归。如最经典的例题:
原公式
而我们
这里我们对两个产生式分析(第三个没有左递归):
- 将E当作P,+T当作α,T当作β。
- 将T当作P,*F当作α,F当作β。
于是消除左递归后,结果为:
当有多个α,β时,公式如下:
左递归可分为直接左递归和间接左递归,两者区别在于是否可以直接看出。间接左递归需要代入等步骤。
消除回溯
这里就相当于提取公因式,把一样的提出来,不一样的用另一个代替。说一个例子就懂了,很简单的。
G(S):
E->T+F|T+α|ε
就可以变为:
G(S):
E->TE'|ε
E'->+F|+α
你看看,是不是很简单呢。
然后一般题目会是改造成LL(1)文法,这种题进行消除左递归和消除回溯就行,结果就是LL(1)文法了。
接下来是FIRST和FOLLOW集合的求解
这里我引用小落0117的文章
链接: link
求First(x)的算法:
若x∈VT ,则first(x)={
x}
若X∈VN ,且有产生式 Xa… , a∈VT ,则a∈first(X)
若X∈VN ,xε,则ε∈first(X)
若X∈VN ,且有产生式 XY1Y2…Yn ,其中Y1,Y2,… Yn都∈VN
当Y1,Y2,… Yi-1都能推导出ε时(1<=i<=n),
则 first(Y1) - {
ε}∈first(X)
first(Y2) - {
ε}∈first(X)
…
first(Yi) ∈first(X)
当Y1,Y2,… Yn都能推导出ε时,
则first(X) = (first(Y1)-{
ε})∪(first(Y2)-{
ε})∪ ……
∪(first(Yn)-{
ε})∪{
ε}
求follow集算法:
设S为开始符号,把{
#}加入Follow(S)中(#为句子括号)
若A→αBβ,则把 First(β)–{
ε} 加入Follow(B)中,
如果β ε,则把 Follow(A)也加入Follow(B)中。
反复2,直到每个VN的Follow集不再增大为止。
这书上的算法解释,谁特喵能看的懂啊,书本就是把简单易懂的知识变成一堆又长又难懂的句子,还是看看简单的解释吧!
先举例子
S→AB
S→bC
A→ε
A→b
B→ε
B→aD
C→AD
C→b
D→aS
D→c
求他的first,follow
First(S) =(First(A)-{ε})∪(First (B)-{ε}) ∪{ε}∪{b}
={a,b,ε}
因为A的first有ε,B的first有ε,S->AB,所以是First(A)-{ε})∪(First (B)-{ε}) ∪{ε},然后S->bC,所以再加一个b,就是First(A)-{ε})∪(First (B)-{ε}) ∪{ε}∪{b},
First (A)={b, ε}
没什么好解释的
First (B)={a, ε}
ε不用解释,就是B->ε,所以有他,a就是因为B->aD,第一个非终结符是a所以有a,那要不要加上D的first呢,就是a和c,答案是不用,就只要aD里面的a就可以
First ( C)={a,b,c}
C->AD这一句,AD都是非终结符,所以要找A和D的first集,D的是a,c,A的是b,ε,因为不是AD同时都能推出ε所以C的first是A和D的first的并集减去ε,还要加上b,因为有C->b这一句
First (D)={a,c}
D->c不用解释,D->aS这一句,不用加上S的first!!!
First (AB)={a,b,ε}First (bB)={b}
First (ε)={ε} First (b)={b}
First (aD)={a} First (AD)={a,b,c}
First (aS)={a} First ©={c}
AB同时能够推出ε,所以first(AB)就是A和B的first的并集减去ε再并上ε
bB的first就是b,不用加上B的first
ε的就是ε,b就是b,c就是c,只有一个终结符ε没什么好说的
一个终结符和一个非终结符的,就要那个终结符就可以,不用管后面那个非终结符,
两个非终结符的要看是不是他们两个同时能推出ε,能就有ε,要是有一个不能推出ε,那first集就没有ε
AB有ε是因为AB都能推出ε,AD没有是因为A能D不能推出ε
以上first集就求完了,是不是很简单,我搞了一上午。。。
接下来求follow集
从开始符号S开始推倒,开始符号的follow里面一定要有#,且follow集里没有ε
所以开始符号的S的follow集要有#,
follow是找->后面的,比如找S的follow,就要看谁的->后面有S,D->aS里面有S,然后在看D->aS的S后面有没有别的符号,没有就加上D的follow集,如果有,就加上后面那个字母的first集里面除了ε以外的符号,在看这个字母能不能推出ε,如果能,就再加上->左边的那个字母的follow
看A的follow,首先找所有->后面有A的,找到了S->AB,C->AD,先看S->AB,A后面有B,所以要加上B的first集里面除了ε的其他符号,再看B能不能在有限的步骤里推出ε,有B->ε这句,所以能,就要再加上->左边的S的follow集,所以目前的A的follow集里面有a,和follow(S),再看C->AD这一句,A后面有D,所以要加上D的first集里面除了ε的其他的,再看B能不能在有限的步骤里推出ε,D不能,所以不用加->左边的C的follow,所以A的follow就是a,follow(S),a,c,但是如果有重复的,就只要一个,所以最终就是a,c,follow(S),这个follow(S)到后面还要算出来的,不能就这样写
看B的follow,找所有->后面有B的,找到了S->AB,看B后面有字母吗?没有,就加上->左边的S的follow,所以follow(B)=follow(S)
看C的follow,找所有->后面有C的,找到了S-bC,看C后面有字母吗?没有,就加上->左边的S的follow集,所以follow©=follow(S)
看D的follow,找所有->后面有D的,找到了B->aD。C->AD,这两句D后面都没有字母,所以加上->左边的B和C的follow,所以follow(D)=follow(B)并上follow©
最终要把以上的follow都求出来,看follow(S)=#+follow(D),follow(D)=follow(B)+follow©,所以follow(S)=#+follow(B)+follow©,follow(B)=follow(S),follow©=follow(S)所以follow(S)=#+follow(S)+follow(S),所以follow(S)就是#,follow(B),follow©,follow(D)也都是#,所以follow(A)就是ac,#,求完了,以上所有的+代表求并集
下面讲解LL(1)文法证明:
这里书上的公式还挺清楚的
就是说对那些有 | 的产生式分析,像E->F|P|S,这里他就要拿出来了,而像E->R,就不用讨论,拿出来后开始分析
1.如果 | 里面含有ε,就先证明右侧的每个部分FIRST集合不相交,再证明->右侧的每个部分(除ε)FIRST集合与左侧FOLLOW集合不相交。
2.如果 | 里面不含有ε,直接判断右侧所有部分FIRST集合不相交就行。
接下来是预测分析表的构建
这里其实也非常简单的
这是ppt的,谁看的懂啊?
其实就是构建表格,行为用到的非终结符,列为用到的终结符。
从行出发,对这个产生式分析,当出现E->F这种时,就找此时的FIRST集合,在所需位置填入产生式E->F;当出现E->ε时,就看E的FOLLOW集合,在所需位置填入产生式E->ε。
你们可以用下面的例子对比着理解
下面是我学校留的作业,你们也可以看着学习与理解。