FIRST集合、FOLLOW集合及LL(1)文法求法


FIRST集合

定義

可從α推導得到的串的首符號的集合,其中α是任意的文法符號串。

規則

計算文法符號 X 的 FIRST(X),不斷運用以下規則直到沒有新終結符號或 ε可以被加入為止 :

(1)如果 X 是一個終結符號,那么 FIRST(X) = X。

(2)如果 X 是一個非終結符號,且 X ->Y1 Y2 … Yk是一個產生式,其中 k≥1,那么如果對於某個i,a在 FIRST(Y1)、FIRST(Y2)… FIRST(Yi-1)中,就把a加入到 FIRST(X) 中。

(3)如果 X ->ε是一個產生式,那么將ε加入到 FIRST(X)中。


以上是書上的官方規則,不僅讀起來很拗口,理解也很累。

下面看一下精簡版的規則(從別人 @櫻草書 那里看來的,感覺很棒,這里引用一下):
(1)如果X是終結符,則FIRST(X) = { X } 。
(2)如果X是非終結符,且有產生式形如X → a…,則FIRST( X ) = { a }。
(3) 如果X是非終結符,且有產生式形如X → ABCdEF…(A、B、C均屬於非終結符且包含 ε,d為終結符),需要把FIRST( A )、FIRST( B )、FIRST( C )、FIRST( d )加入到 FIRST( X ) 中。
(4)如果X經過一步或多步推導出空字符ε,將ε加入FIRST( X )。

實踐

記得,曾經有人說過:

只讀,就會白給

下面以這個文法為例講解一波,會用精簡版規則,更容易理解一些:

E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id

   
   
  
  
          
  • 1
  • 2
  • 3
  • 4
  • 5
  1. FIRST(E) = FIRST(T) 根據規則3,很容易理解,這里要注意的由於T不含ε,所以遍歷到T就停止了,E’不會加入進來
  2. FIRST(E’) = FIRST(+) ∪ FIRST(ε)= { +, ε } 根據規則2和4,,很好理解
  3. FIRST(T) = FIRST(F) 根據規則3,和第一條推導過程一樣
  4. FIRST(T’) = FIRST() ∪ FIRST(ε)= { , ε } 根據規則2和4,和第二條推導一樣
  5. FIRST(F) = FIRST( ( ) ∪ FIRST(id)= { ( , id } 根據規則2

結果:

FIRST(E) = FIRST(T) = FIRST(F) = { ( , id }
FIRST(E') = FIRST(+) ∪ FIRST(ε)= { + ,  ε }
FIRST(E') = FIRST(*) ∪ FIRST(ε)= { * ,  ε }

   
   
  
  
          
  • 1
  • 2
  • 3

FOLLOW集合

定義

對於非終結符號A,FOLLOW(A) 被定義為可能在某些句型中緊跟在A右邊的終結符號集合。

規則

計算文法符號 X 的 FOLLOW(X) ,不斷運用以下規則直到沒有新終結符號可以被加入任意FOLLOW集合為止 :

(1)將$加入到FOLLOW(X)中,其中S是開始符號,而$是輸出右端的結束標記。

(2)如果存在一個產生式S->αXβ,那么將集合FIRST(β)中除ε外的所有元素加入到FOLLOW(X)當中。

(3)如果存在一個產生式 S->αX , 或者S->αXβ且FIRST(β)中包含ε , 那么將集合FOLLOW(S)中的所有元素加入到集合FOLLOW(X)中。

實踐

還是用之前的例子來做

E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id

   
   
  
  
          
  • 1
  • 2
  • 3
  • 4
  • 5
  1. FOLLOW(E) ,根據規則1,首先把$加入進來,根據規則2,可以得出 FOLLOW(E) = { ) , $ }
  2. FOLLOW(E’) = FOLLOW(E) = { ) , $ } 根據規則3
  3. FOLLOW(T) = FIRST(E’) ∪ FOLLOW(E) = { + , ) , $ } 根據規則2
  4. FOLLOW(T’) = FOLLOW(T) = { + , ) , $ } 根據規則3
  5. FOLLOW(F) = FOLLOW(T) ∪ FIRST(T’) = { * , + , ) , $ } 根據規則2和3

結果:

FOLLOW(E) = FOLLOW(E') = { ) , $ }
FOLLOW(T) = FOLLOW(T') = { + , ) , $ }
FOLLOW(F) = { * , + , ) , $ }

   
   
  
  
          
  • 1
  • 2
  • 3

LL(1)文法

解釋

LL(1) 中第一個“L”表示從左向右掃描輸入,第二個“L”表示產生最左推導,而“1”表示在每一步中只需要向前看一個輸入符號來決定語法分析動作。

定義

對於文法LL(1)文法G,當且僅當G的任意兩個不同產生式 A -> α | β
(1)不存在終結符號a使得α和β都能推導出以a開頭的串。
(2)α和β中最多只有一個可以推導出空串。
(3)如果 β=》ε ,那么α不能推導出任何以FOLLOW(A)中某個終結符號開頭的串。

可能很多人看的雲里霧里,解釋一下:
(1)和(2)意思是α和β的FIRST集合相交。(3)是指如果FIRST(α)中有 ε,那么FIRST(β)和FOLLOW(A)是不相交的集合,反之一樣。

預測分析表的構建

方法:
對於文法G的每個產生式 A->α ,進行如下處理
(1)對於FIRST(α)中每個終結符號a,將 A->α 加入到 M[A,a] 中。
(2)如果 ε在FIRST(α)中,那么對於FOLLOW(A)中每個終結符號b,將 A->α 加入到 M[A,b] 中。如果 ε在FIRST(α),且$在FOLLOW(A)中,也將 A->α 加入到 M[A,$] 中。

還是以之前的例子示例

E -> T E'
E' -> + T E' | ε
T -> F T'
T' -> * F T' | ε
F -> ( E ) | id

   
   
  
  
          
  • 1
  • 2
  • 3
  • 4
  • 5

1.先求FIRST和FOLLOW集合:

FIRST(E) = FIRST(T) = FIRST(F) = { ( , id }
FIRST(E') = FIRST(+) ∪ FIRST(ε)= { + ,  ε }
FIRST(T') = FIRST(*) ∪ FIRST(ε)= { * ,  ε }
FOLLOW(E) = FOLLOW(E') = { ) , $ }
FOLLOW(T) = FOLLOW(T') = { + , ) , $ }
FOLLOW(F) = { * , + , ) , $ }

   
   
  
  
          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.然后構建一個這樣的表
在這里插入圖片描述
3.然后依次填入非終結符號
在這里插入圖片描述
4.按照規則1填寫其余內容
在這里插入圖片描述
5.按照規則2填寫內容
在這里插入圖片描述
至此整個構建全部完成

                                </div>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM