转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|ε,互相加入到集合中去)