轉First集合和Follow集合的求法(修改含例子)

對於終結符和非終結符的理解:spa

 

終結符:通俗的說就是不能單獨出如今推導式左邊的符號,也就是說終結符不能再進行推導。遞歸

非終結符:不是終結符的都是非終結符。語言

如:A->B,則A是非終結符;A->id,則id是終結符。集合

(通常書上終結符用小寫,非終結符用大寫。)字符集

 

文法產生語言句子的基本思想:co

 

從識別符號(開始符)開始,把當前產生的符號串中的非終結符替換爲相應規則右部的符號串,直到所有由終結符組成。因此文法產生句子的基本思想就是基於產生式(例如A->num)的替換,當全部的非終結符都被終結符替換時,推導結束。字符

 

FIRST集求法:background

 

我 對First集的理解:first集應該就是求一個表示文法的字串(通常指非終結符,終結符的first集就是它自身)開頭的全部可能出現的字符的集合。 例如A->aC | bB | cD,根據這個產生式,就能夠知道,非終結符A,被替換後,它開頭可能出現字符有a、b 、c, 因此 {a,b,c}是First(A)的一個子集。

 

求First集的步驟:

  1. 若X->a..,則將終結符a加入FIRST(X)中;(注意非終結符的狀況)

  2. 若X->e ,則將終結符e加入FIRST(X)中(e表示空集);

  3. 若 X->BC..D,則將First(B)全部元素(除了空集)加入First(A),而後檢測First(B),若First(B)中不存在空集, 即e,則中止,若存在則向B的後面查看,將First(C)中全部元素(除了空集)加入First(A),而後再檢測First(C)中是否有e...直 到最後,若D以前的全部非終結符的First集中都含有e,則檢測到D時,將First(D)也加入First(A),若First(D)中含有e,則將 e加入First(A)。

對於第三條,其實也很好理解,就是說當X推導出一個字串時,D前面的非終結符均可能推出空串,這個時候,X推出的串的首部,就不是那些推出空串的非終結符了,而是這些推出空串的非終結符後面的文法符號所推導出的字串。

                例題:設文法G(S):

                           S->S+aF|aF|+aF

                           F->*aF|*a

                       (1)消除左遞歸和左因子。

                       (2)構造相應的FIRST集合和FOLLOW集合。

  解析:首先,第一個式子,消除左遞歸。S->aFS’|+aFS'。S'->+aFS'|ε             (此處的ε和e同樣的 不一樣的書上印刷的不一樣)

              而後,第二個式子,消除左因子。F->*aF’,F'->F|ε

             第三步,求各個非終結符的FIRST集合。FIRST(S)={a,+}     由於S能夠導出首字母爲終結符a的產生式,和首字符爲+的產生式。

                                                                                    FIRST(S‘)={+,ε}  FIRST(F)={*},FIRST(F’)={*,ε}

FOLLOW集的求法:

 

對Follow集,其實也差很少,它應該是指非終結符推出的字串最末端後可能出現的全部字符的集合。例如Follow(U)所表達的是句型中非終結符U全部可能的後隨終結符號的集合,特別地,「$」是識別符號的後隨符。注意Follow集合是從開始符號S開始推導。

 

求Follow集的步驟:

  1. 對文法開始符號S,置$於FOLLOW(S)中;      (也就是說有關S的FOLLOW集合中,都包含$,也有書中表示爲#)

  2. 對於產生式:A->aBC,將除去空集e的First(C)加入Follow(B)中;      (B後面跟着的就是C的首部字符,注意若是是終結符也要搞上)

  3. 對於產生式:A->aB或者A->aBC,(其中C能夠推導出空串,C=>*e,即空串屬於C的first集合),則將Follow(A)加入Follow(B)中。                                                   (注意:此處a能夠是空,也能夠是其餘文法符號);

                      (A->aB ,那麼A推出字串的末端後字符集合,與B推出字串的末端後字符集合,是等價的。)

注意:follow集合是要將全部的產生式都找出來,來求非終結符的follow集合。

             剛剛的例題:

                     FOLLOW(S)={#},FOLLOW(S')={#},能夠看出S和S‘ 並無其餘的末端。

                     FOLLOW(F)={+,#}    (緣由是S->aFS’|+aFS'。S'->+aFS'|ε  ,由第二條,講S和S’的FOLLOW集合加入到FOLLOW(F)中,且F後面有S‘,所以將                                                                                           FIRST(S’)出去空集之外,也加入到FOLLOW(F)中 )

                     FOLLOW(F')={+,#},(F->*aF’,F'->F|ε,互相加入到集合中去)

相關文章
相關標籤/搜索