怎么求编译原理自顶向下分析的first集follow集和select

转载自:https://blog.csdn.net/luobida222/article/details/73542851

期末复习中,编译原理要搞死我了。。。。

在被编译原理搞死之前,我要搞死编译原理。。。。

求First(x)的算法:
若x∈VT ,则first(x)={x}
若X∈VN ,且有产生式 Xa… , a∈VT ,则a∈first(X)
若X∈VN ,xε,则ε∈first(X)
若X∈VN ,且有产生式 XY1Y2…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)-{ε})∪{ε}

(上面那个是老师ppt里面粘过来的,我看不懂,能不能说人话。。。这是什么鬼算法。。。你要是也看不懂就别理他了,看我下面的例子和解释)

求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,select

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)={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里面一定要有#,

所以开始符号的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(C)=follow(S)

看D的follow,所有->后面有D的,找到了B->aD。C->AD,这两句D后面都没有字母,所以加上->左边的B和C的follow,所以follow(D)=follow(B)并上follow(C)

最终要把以上的follow都求出来,看follow(S)=#+follow(D),follow(D)=follow(B)+follow(C),所以follow(S)=#+follow(B)+follow(C),follow(B)=follow(S),follow(C)=follow(S)所以follow(S)=#+follow(S)+follow(S),所以follow(S)就是#,follow(B),follow(C),follow(D)也都是#,所以follow(A)就是ac,#,求完了,以上所有的+代表求并集

再看select怎么求

对于A->a,如果a=/>ε,那么select(A->a)=first(a),如果a=*>,那么select(A->a)就是first(a)-ε+follow(A)

看select(S->AB),AB都能推出ε,所以select(S->AB)=first(AB)-ε+follow(S)所以结果是a,b,#

看select(S->bC),bC不能推出ε,所以是first(bC),结果是b

看select(A->ε),A能推出ε所以是first(ε)-ε+follow(A)结果a,c,#

看select(A->b),这里的A是推出b不是ε所以是first(b),结果是b

看select(B->ε),B能推出ε,所以是first(ε)-ε+follow(B),结果是#

看select(B->aD),这里B不能推出ε,所以是first(aD),结果是a

看select(C->AD),这里D不能推出ε,所以算AD不能推出ε,就是first(AD),结果是a,b,c

ε,所以是first(b),结果是b

看select(D->aS),这里不能推出ε,所以是first(aS),结果是a

看select(D->c),这里D不能推出ε,所以是first(c),结果是c

LL(1)文法

是自顶向下分析,从左到右扫描输入串,最左推导,只需向右看一个符号就可以决定如何推倒

LL(1)文法满足条件:左部相同的产生式的select集的交集为空,并且产生式的右部不能同时推导出ε,那么这个文法是LL(1)文法,否则不是

上面的文法select(C->AD)和select(C->b)的交集是b不是空,select(S->AB)和select(S->bC)的交集也是b不是空,所以这不是一个LL(1)文法


猜你喜欢

转载自blog.csdn.net/dfsethtdfd/article/details/80291797