1. 程式人生 > >語法分析--左遞迴的消除,FIRST集合FOLLOW集的求解

語法分析--左遞迴的消除,FIRST集合FOLLOW集的求解

語法分析–左遞迴的消除,FIRST集合FOLLOW集的求解

左遞迴的消除

如果自一個文法中,存在一個非終端符號A,使得對某個串α,存在一個推導A→(*)Aα.(其中 →(*)表示可以經過多步推導。)則該文法為左遞迴文法(left recursive).由於自頂向下語法分析方法不能處理左遞迴的文法,因此需要一個轉換方法來消除左遞迴。

 對於左遞迴的產生式 A → Aα | β, 替換為非左遞迴的產生式如下(其中,ε表示空串):
  A → βA’
  A’ → αA’ | ε

這樣的替換不會改變可從A推導得到的串的集合(證明省略)。該規則本身已經足夠用來處理許多文法。

對文法
  E → E+T | T
  T → T*F | F
  F → (E) | id

通過使用上述的方法,將其轉換為非左遞迴的文法,結果如下:

  E → TE’
  E’ → +TE’ | ε
  T → FT’+
  T’ → +FT’ | ε
  F → (E) | id

在上述過程中,E → E+T | T被替換為E→TE’ 和E’ → +TE’|ε。類似的,T和T’的新產生式也是通過消除立即左遞迴得到的。

FIRST和FOLLOW集

在語法分析部分,使用自頂向下和自底向上的語法分析器的構造可以使用文法G相關的兩個函式,即FIRST和FOLLOW。

FIRST

FIRST(α)被定義為可從α推導得到的串的首符號的集合,其中α是任意的文法符號串。如果α→(*)ε,那麼ε也在FIRST(α)中。
FIRST集的產生規則。計算各個文法符號X的FIRST(X)時,運用下面的規則,知道沒有新的終端符號或ε可以被加入到任何的FIRST集合中為止:

  1) 如果X是一個終端字元,那麼FIRST(X)=X
  2) 如果X是一個非終端字元,且X→Y1Y2Y3…Yk是一個產生式,其中k≥1,那麼如果對於某個i,a在FIRST中(Yi)中且ε在所有FIRST(Y1),FIRST(Y2)..FIRST(Yi-1)中,就把a加入到FIRST(X)中。Y1Y2Y3..Yk Yi 中的123ki表示的為小標 而不是終端符號
  3) 如果X→ε是一個產生式,那麼將ε加入到FIRST(X)中。

第二條規則,也就是說,FIRST(Y1)中的每個元素都在FIRST(X)中,且,如果FIRST(Y1)中存在ε(空串),則FIRST(Y2)也存在FIRST(X).對後面的同理

FOLLOW

對於非終端符號,FOLLOW(A)被定義為可能在某些句型中緊跟在A右邊的終端字元的集合。例如,如果有S→αAaβ(其中α,β是文法符號),那麼終端符號a就在FOLLOW(A)中。如果A是某些句型的最右符號,則也在FOLLOW(A)中。其中 也在FOLLOW(A)中。其中也在FOLLOW(A)中。其中為特殊的“結束標記”符號。
FOLLOW集的產生規則計算各個文法符號X的FOLLOW(A)時,運用下面的規則,知道沒有新的終端符號可以被加入到任何的FOLLOW集合中為止:


  1) 將放入到FOLLOW(S)中,其中S是開始符號,而 放入到FOLLOW(S)中,其中S是開始符號,而放入到FOLLOW(S)中,其中S是開始符號,而是輸入右端的結束標記
  2) 如果存在一個產生式A→αBβ,那麼FIRST(β)中除了ε外的所有符號都在FOLLOW(B)中。
  3) 如果存在一個產生式A→αB,或存在產生式A→αBβ且FIRST(β)包含ε,那麼FOLLOW(A)中的所有符號都在FOLLOW(B)中。