2020編譯原理(五)------繞繞繞的First,Follow,Select集

,爲了更好的進行自頂向下的語法分析,以及判斷LL(1)文法,最後介紹的便是FIRST集,FOLLOW集和SELECT集.

一. FIRST 集

爲了更好的理解,我們通過一個例子來挨個介紹。
文法G[S]
S->AB|bC
A->#|b
B->aD|#
C->AD|b
D->aS|c

【注】:#表示空
1.FIRST集是一個文法符號串所可能推導出的符號串的第一個終結符的集合
2.因爲有公共左因子的問題,所以要引入FIRST集的概念,公共左公因子是指在文法的產生式集合中,某個非終結符的多個候選式具有相同的前綴。

瞭解了一些基本概念之後,我們就進入正題分析一下各個非終結符的FIRST集。

FIRST(S)
由S->AB和S->bC,可以知道FIRST(S)={b},
然後S->AB先放在一邊。

由A->#|b,可以得出S->B和S->bB,FIRST(S)={b},進一步推出S->aD和S->#
最後便可總結起來:FIRST(S)={a,b,#)

二.FOLLOW集

1.定義:設G=(Vt,Vn,P,S),上下文無關文法,A∈Vn,S是開始符號,FOLLOW(A)={a|S=*>uAb&&a∈Vt,a∈FIRST(b),u∈Vt,b∈V*}
只有非終結符的FOLLOW集纔有定義

2.對於文法的開始符號S,置 # 於 FOLLOW(S)中.
若 A →aBβ 是一個產生式, 則把 FIRST(β)\ε 加至 FOLLOW(B) 中.
若 A →aB 是一個產生式,或 A →aBβ是一個產生式而 β⇒ε,則把 FOLLOW(A) 加至 FOLLOW(B) 中.
【例】
S->BS’
S’->aB|ε
B->DB’
B’->B|ε
D->d|ε
求各個非終結符的FOLLOW集
FOLLOW(S)
因爲S 是開始符號,所以將#置於FOLLOW(S)中,在產生式右部找S,沒有所以FOLLOW(S)={#}
FOLLOW(S’)
根據第三條規則,S->BS’,將FOLLOW(S)加到FOLLOW(S’),然後再找其他的S’在右部的,沒有就過了。所以FOLLOW(S’)={#}
FOLLOW(B)
根據第二條規則,S->BS’,FOLLOW(B)=FIRST(S’)\ε={a}
根據第三條規則,S’->aB,FOLLOW(B)=FOLLOW(S’)={#}
還有就是第三條規則,S->BS’,又因爲S’->ε,S->B,FOLLOW(B)=FOLLOW(S)={#}
綜上所述:FOLLOW(B)={a,#}
FOLLOW(B’)
根據第三條規則,B->DB’,FOLLOW(B’)=FOLLOW(B)={a,#}
FOLLOW(D)
根據第二條規則,B->DB’,FOLLOW(D)=FIRST(B’)\ε={b}

三.SELECT集

1.Select集合就是產生式左部的可能的推導結果的起始符號。

2.Select(A–>B)就是求這個產生式中A可能推導出起始符號集合(不包含空串ε)。
求Select集合可分如下幾種情況:

  • A–>X (X爲任意文法符號串,不限於非終結符或單個符號),並且X不能推導出空串 ε,根據定義,顯然A推出的符號串起始就是X的起始,也就是First(X).Select(A–>X)= First(X)
  • A–>X (X爲任意文法符號串,不限於非終結符或單個符號),並且X能推導出空串ε,根據定義,顯然First(X)屬於Select(A–>X),此外,當X推導爲空串時,顯然A 也推導爲空串,那麼此時推導出的符號串就會是A後面的符號的推導結果。也就是 Follow(A),所以,此時Follow(A)也屬於Select(A–>X)
  • Select集合中不包括空串ε,但有可能會包含#(句子括號)。

四.最後是一道例題,可以很好地利用一下上面所有規則。

S→AB|bC
A→b|ε
B→aD|ε
C→AD|b
D→aS|c
求FIRST,FOLLOW,SELECT集
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

經過一番繞繞繞的推導,終於撥開雲霧見青天,具體過程歡迎大家一起探討~~~~~

修正:SELECT集 中

select (A->ε) = First (ε)- ε + Follow(A) = {a,b,#}

謝謝熱心網友批評指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章