FIRST集合
定義
令G是一個不含左遞歸的文法,對G的所有非終結符的每個候選a定義它的終結首符集FIRST(a)爲:
FIRST(α) = { a│α ⇒∗ a…, a∈VT }
若α ⇒∗ ε ,則規定ε∈FIRST(α)。
FIRST(α)被定義爲從α推導得到的句子的首符號的集合,α是任意的文法符號串。
n非終結符的FISRT集合中有空串與該非終結符屬於NULLABLE集合等價。
FIRST集合構造
構造每個文法符號的FIRST集合
第一種說明:
對於文法G的每個文法符號X∈VT∪VN:
- 若 X ∈ VT,則 FIRST(X) = { X }
- 若 X ∈ NULLABLE,則把 ε 加入FIRST(X)
- 若 X ∈ VN,且 X → a…, a ∈ VT,則把a加入到FIRST(X)中
- 若 X ∈ VN,且 X → Y…, Y ∈ VN,則把FIRST(Y) - {ε}加到FIRST(X)中
- 若 X →Y1Y2 … Yi , 且 Y1, Y2, … ,Yi-1 ∈ nullable,則把 FIRST(Yi) - {ε}加到FIRST(X)中
- 若 FIRST(Ym) ∈ NULLABLE(1<=m<=i),則ε∈FIRST(X)
第二種說明:
對每一X∈VT∪VN,連續使用下面的規則,直至每個集合FIRST不再增大爲止:
- 若X ∈ VT,則FIRST(X)={X}。
- 若X ∈ VN,且有產生式X→a…,則把a加入到FIRST(X)中;若X→ε也是一條產生式,則把 ε 也加到FIRST(X)中。
- 若X→Y…是一個產生式且Y ∈ VN,則把FIRST(Y)中的所有非 ε- 元素都加到FIRST(X)中;若X→Y1Y2…Yi-1Yi…Yk是一個產生式,Y1,…,Yi-1都是非終結符,對於任何j,1<=j<=i-1,FIRST(Yj)都含有 ε (即Y1…Yi-1 ⇒∗ε), 則把FIRST(Yi)中的所有非 ε-元素都加到FIRST(X)中;若所有的FIRST(Yj)均含有 ε,j=1,2,…,k,則把 ε 加到FIRST(X)中。
如果上面兩個構造方法看不懂也不要緊,我們大白話講一下
第三種說明(這種比較好理解):
對於 X -> ... 這條產生式而言,
- 若右邊第一個符號是終結符或 ε ,則直接將其加入 FIRST(X)
- 若右邊第一個符號是非終結符,則將其 FIRST 集的的非 ε 元素加入 FIRST(X)
- 若右邊第一個符號是非終結符而且緊隨其後的是很多個非終結符,這個時候就要注意是否有 ε 。
- 若第 i 個非終結符的 FIRST 集有 ε ,則可將第 i+1 個非終結符去除 ε 的 FIRST 集加入 FIRST(X)。
- 若所有的非終結符都能夠推導出 ε ,則將 ε 也加入到 FIRST(X)
以上三種說明大致意思都是相同的
例題
文法G:
E → TE'
E' → +TE’│ε
T → FT'
T' → *FT'│ε
F → (E)│i
求每個非終結符號的FIRST集合
這是一道非常經典的例題,下面我們一起來看一下
因爲FIRST集合是要不斷重複進行的,我們可以多次循環構造它(以下均使用第三種說明)
第一次循環
//E的產生式緊跟的是兩個非終結符,根據構造法第二條,FIRST(E)=FIRST(T),而FIRST(T)我們還沒求出來,所以我們這項暫時爲空
FIRST(E) = { }
//E'的產生式緊跟的是非終結符+,根據構造法第一條,將其加入到FIRST(E')中,產生式中還可以推導出ε,將ε也加入到FIRST(E')中
FIRST(E') = {+,ε}
//T的產生式緊跟的是FT'兩個非終結符,根據構造法第二條,FIRST(T)=FIRST(F),而FIRST(T)我們還沒求出來,所以我們這項暫時爲空
FIRST(T) = { }
//T'的產生式緊跟的是非終結符*,根據構造法第一條,將其加入到FIRST(T')中,產生式中還可以推導出ε,將ε也加入到FIRST(T')中
FIRST(T') = {*,ε}
//F的產生式緊跟的是非終結符(,根據構造法第一條,將其加入到FIRST(T')中,產生式中還可以推導出i,將i也加入到FIRST(F)中
FIRST(F) = {(, i}
//第一次循環之後,有FIRST集合發生改變,再次循環,直到所有FIRST集合不發生改變爲止
第二次循環
FIRST(E) = { } //沒有得到FIRST(T),依舊不能得到FIRST(E),所以爲空
FIRST(E') = {+,ε} //不變
FIRST(T) = {(, i}
//T的產生式緊跟的是非終結符F,根據構造法第二條,將FIRST(F)中的元素加入到FIRST(T)中
FIRST(T') = {*,ε} //不變
FIRST(T) = {(, i} //不變
//第二次循環之後,FIRST集合發生變化,再次循環
第三次循環
FIRST(E) = {(, i} //根據構造法第二條,將將FIRST(T)中的元素加入到FIRST(E)中
FIRST(E') = {+,ε} //不變
FIRST(T) = {(, i} //不變
FIRST(T') = {*,ε} //不變
FIRST(T) = {(, i} //不變
//第三次循環之後,FIRST集合發生改變,接着循環
第四次循環
FIRST(E) = {(, i}
FIRST(E') = {+,ε}
FIRST(T) = {(, i}
FIRST(T') = {*,ε}
FIRST(T) = {(, i}
所有FIRST集合都不改變,完成FIRST集合的構造
構造任意符號串的FIRST集合
對文法G的任何符號串α=X1X2…Xn構造集合FIRST(α)
FIRST(α)={ a│α⇒∗ a…, a∈VT }
α = X, X∈VT∪VN
α = X1X2…Xn, X∈VT∪VN
1. 置FIRST(α)=FIRST(X1) \ {ε};
2. 若對任何1<=j<=i-1,ε∈FIRST(Xj),則把FIRST(Xi) \ {ε}加至FIRST(α)中;特別是,若所有的FIRST(Xj)均含有ε,1<=j<=n,則把ε 也加至FIRST(α)中。顯然,若α=ε則FIRST(α)={ ε }。
如果能理解上面對文法符號的構造,對任意符號串的構造就很好理解了
如有錯誤,歡迎指正!