FIRST集 FOLLOW集 和 SELECT集

2021-08-07 12:00:35 字數 4121 閱讀 8156

first(a)為a的開始符或者首符號集。

設g=(vt,vn,s,p)是上下文無關文法 ,first(α)=   

特別的,若α能推導出ε,則規定ε∈first(α).

若x∈vt,則first(x)=。(簡單講,終結符的first集就是它本身)

若x∈vn,且有產生式x→a…,a∈vt, 則 a∈first(x)x→ε,則ε∈first(x)。 (簡單講,若是非終結符x,能推導出以終結符a開頭的串,那麼這個終結符a屬於first(x),若x能夠推導出空符號串ε,那麼空符號串ε也屬於x的first集)

x→y…是乙個產生式且y ∈vn 則把first(y)中的所有非空符號串ε元素都加入到first(x)中。(這個可以理解吧)

若x∈vn;y1,y2,…,yi∈vn,且有產生式x→y1 y2… yn;當y1 y2… yn-1都能推導出ε時,則first(y1)、first(y2)、…、first(yn-1)的所有非空元素和first(yn) 包含在first(x)中。即: first(x)=(first(y1)- )∪(first(y2)- )∪…∪(first(yn-1)-)∪

當(4)中所有yi 能夠推導出ε,(i=1,2,…n),則 first(x)=(first(y1)-)∪(first(y2)- ∪…∪(first(yn) -)∪

反覆使用上述②~⑤步直到每個符號的first集合不再增大為止。

文法g [s]為:

- s→ab

- s→bc

- a→ε

- a→b

- b→ε

- b→ad

- c→ad

- c→b

- d→as

- d→c

求每個非終結符的first集?

解:對於非終結符s,s的開始符有終結符b和非終結符a,根據上面定義(2)把b加入first(s),由上面的定義(3)把first(a)中的所有非空符號串ε元素都加入到first(s)中,而且因為s→ab符合上面的定義(4)和(5),所以first(s)=(first(a)-)∪(first(b) -)∪那麼先求first(a)和first(b),a的開始符有終結符b和空符號串ε,由定義(1)和定義(2)全部加入first(a),也就是first(a)=,同理,first(b)=,這樣first(s)也就求出來了,first(s)=,其實回過頭來看之所以要反覆呼叫定義(2)~(5),是因為開始符中a可能為空字串ε,所以要考慮a後面的情況。

再求,first(c),由定義(1),把b加入first(c),再由定義(4),first(c)=(first(a)- )∪,先求first(d),易知,first(d)=,所以first(c)=

對於終結符而言,first集中的元素只有它本身

對於非終結符而言,如果開始符是終結符或者空符號串ε,則加入其first集中;若開始符是非終結符,則要加入它的不含ε的first集,並考慮其為ε時的情況。

follow(a)={a|s能推導出μaβ,且a∈vt,a∈first(β),μ∈vt* ,β∈v+},若s能推導出μaβ,且β能推導出ε, 則#∈follow(a)。 也可定義為:follow(a)= ,若有s能推導出…a,則規定#∈follow(a) ,這裡我們用『#』作為輸入串的結束符,或稱為句子括號。

如:#輸入串#。

follow(a)為非終結符a的後跟符號集合。

設g=(vt,vn,s,p)是上下文無關文法,a∈vn,s是開始符號  

需要注意的是,follow(a)集是針對非終結符a的,集合中的元素是終結符,是a的全部後跟符號的集合,當a是文法g的開始符(識別符)時,把『#也加入其中』

設s為文法中開始符號,把加入follow(s)中(這裡「#」 為句子括號)。

若a→αbβ是乙個產生式,則把first(β)的非空元素加入follow(b)中。如果β能夠推導出ε則把follow(a)也加入follow(b)中。

反覆使用(b)直到每個非終結符的follow集不再增大為止。

文法g [e]為:

- e → te』

- e』 → +te』 | ε

- t → ft』

- t』 → *ft』 | ε

- f → (e) | i

求每個非終結符的follow集?

解:先給出它們的first集:(求解方法見上面first集的求解)

first(f)=

first(t』)=

first(t) =

first(e』)=

first(e)=

follow集的求解:

因為e是文法的識別符所以把#加入follow(e),又由規則f → (e) | i得e的後跟符號),所以,follow(e)={ #,) };

follow(e』)= ∵e → te』 ∴follow(e)加入 follow(e』)

follow(t)= ∵e』→ +te』 ∴first(e』)-加入follow(t); 又e』→ε,∴ follow(e』)加入follow(t)

follow(t』)= follow(t)= ∵t → ft』 ∴ follow(t)加入follow(t』)

follow(f)= ∵t → ft』 ∴ follow(f)=first(t』)- ; 又t』→ε ∴ follow(t)加入follow(f)

follow集對於非終結符而言,是非終結符的全部後跟符號的集合,如果後跟終結符則加入,如果後跟非終結符,則加入該非終結符的不含空符號串的first集,特別地,文法的識別符的follow集需要額外的加入『#』。

給定上下文無關文法的產生式a→α, a∈vn,α∈v*, 若α不能推導出ε,則select(a→α)=first(α)   

如果α能推導出ε則:select(a→α)=(first(α) –)∪follow(a)

需要注意的是,select集是針對產生式而言的。

乙個上下文無關文法是ll(1)文法的充分必要條件是:對每個非終結符a的兩個不同產生式,a→α, a→β,滿足select(a→α)∩select(a→β)=空集 其中α,β不同時能推導出ε。

ll(1)文法的含義:

ll(1)文法的判別:當我們需選用自頂向下分析技術時,首先必須判別所給文法是否是ll(1)文法。因而我們對任給文法需計算first、follow、select集合,進而判別文法是否為ll(1)文法。

文法g [s]為:

- s→ab

- s→bc

- a→ε

- a→b

- b→ε

- b→ad

- c→ad

- c→b

- d→as

- d→c

求每個產生式的select集,並判斷文法g是否為ll(1)文法?

解:

select(s→ab)=(first(ab)-)∪follow(s)=   

select(s→bc)=first(bc)=   

select(a→ε)=(first(ε) -)∪follow(a)=   

select(a→b)=first(b)=   

select(b→ε)=(first(ε) -)∪follow(b)=   

select(b→ad)=first(ad)=   

select(c→ad)=first(ad)=   

select(c→b)=first(b)=   

select(d→as)=first(as)=   

select(d→c)=first(c)=

由以上計算結果可得相同左部產生式的select交集為:   

select(s→ab)∩select(s→bc)=∩=≠ф

select(a→ε)∩select(a→b)=∩=ф

select(b→ε)∩select(b→ad)=∩=ф

select(c→ad)∩select(c→b)=∩=≠ф

select(d→as)∩select(d→c)=∩=ф

由ll(1)文法定義知該文法不是ll(1)文法,因為具有相同左部其產生式的select集的交集不為空。

select集的作用是將first集和follow集進行合併,如果兩個文法的左端都是a,若他們的select集交集為空,表明他們是兩個無關的,不會產生不確定性的文法,反之,則表明文法不是ll(1)文法。

first集、follow集 和 select集

first集和follow集的計算

計算first集 根據定義計算 對每一文法符號x v 計算first x a 若x vt,則first x b 若x vn,且有產生式x a a vt,則 a first x c 若x vn,x 則 first x d 若x,y1,y2,yn都 vn,且有產生式x y1 y2 yn 當y1 y2 y...

編譯原理 FIRST集和FOLLOW集

自己的理解 例子如果x是乙個終結符,則first x x 如果x是乙個非終結符,則x y 1y2y 3 yk x rightarrow y 1y 2y 3 cdots y k x y1 y 2 y3 yk 其中k 1 k ge1 k 1。i k,a firs t yi 且fi rst y1 firs...

關於求FIRST集和FOLLOW集

這幾天上課沒怎麼聽進去,導致對求first集和follow集有點模模糊糊的,於是在網上找到乙個部落格,看完就理解了,就轉過來了。來自 對於終結符和非終結符的理解 終結符 通俗的說就是不能單獨出現在推導式左邊的符號,也就是說終結符不能再進行推導。非終結符 不是終結符的都是非終結符。如 a b,則a是非...