這幾天上課沒怎麼聽進去,導致對求first集和follow集有點模模糊糊的,於是在網上找到乙個部落格,看完就理解了,就轉過來了。
來自:對於終結符和非終結符的理解:
終結符:通俗的說就是不能單獨出現在推導式左邊的符號,也就是說終結符不能再進行推導。
非終結符:不是終結符的都是非終結符。
如:a->b,則a是非終結符;a->id,則id是終結符。
(一般書上終結符用小寫,非終結符用大寫。)
文法產生語言句子的基本思想:
從識別符號(開始符)開始,把當前產生的符號串中的非終結符替換為相應規則右部的符號串,直到全部由終結符組成。所以文法產生句子的基本思想就是基於產生式(例如a->num)的替換,當所有的非終結符都被終結符替換時,推導結束。
first集求法:
我對first集的理解:first集應該就是求乙個表示文法的字串(一般指非終結符,終結符的first集就是它自身)開頭的所有可能出現的字元的集合。例如a->ac | bb | cd,根據這個產生式,就可以知道,非終結符a,被替換後,它開頭可能出現字元有a、b 、c, 所以是first(a)的乙個子集。
求first集的步驟:
若x->a..,則將終結符a加入first(x)中;
若x->e ,則將終結符e加入first(x)中(e表示空集);
若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推出的串的首部,就不是那些推出空串的非終結符了,而是這些推出空串的非終結符後面的文法符號所推導出的字串。
follow集的求法:
對follow集,其實也差不多,它應該是指非終結符推出的字串最末端後可能出現的所有字元的集合。例如follow(u)所表達的是句型中非終結符u所有可能的後隨終結符號的集合,特別地,「$」是識別符號的後隨符。注意follow集合是從開始符號s開始推導。
求follow集的步驟:
對文法開始符號s,置$於follow(s)中;
對於產生式:a->abc,將除去空集e的first(c)加入follow(b)中;
對於產生式:a->ab或者a->abc,(其中c可以推導出空串,c=>*e),則將follow(a)加入follow(b)中。
(注意:此處a可以是空,也可以是其他文法符號);
對第二條步驟的理解:follow(b)是b推出的串末端後的字元集合,在a->abc的情形下,b推出串末端後的字符集,也就是c推出串首部字元的集合,即first(c)中除去e的集合。
對於第三條,其實也比較好理解,a->ab ,那麼a推出字串的末端後字元集合,與b推出字串的末端後字元集合,是等價的。
下面有乙個用c++實現的求first集合follow集的程式,寫的不怎麼樣,如有需要可供參考一下。
怎樣求FIRST集 FOLLOW集和SELECT集
終結符 通俗的說就是不能單獨出現在推導式左邊的符號,也就是說終結符不能再進行推導。非終結符 不是終結符的都是非終結符。非男即女,呵呵 如 a b,則a是非終結符。一般書上終結符用小寫,非終結符用大寫。從識別符號 開始符 開始,把當前產生的符號串中的非終結符替換為相應規則右部的符號串,直到全部由終結符...
怎麼求 first集 follow集
判斷該文法是不是ll 1 文法,說明理由 s abc a a b b first集合求法就是 能由非終結符號推出的所有的開頭符號或可能的 但要求這個開頭符號是終結符號。如此題a可以推導出a和 所以first a a,同理first b s可以推導出abc,還可以推導出bc,還可以推導出c,所以fir...
編譯原理 First集和Follow集的求法
自上而下分析 first集求法 first集合最終是對產生式右部的字串而言的,但其關鍵是求出非終結符的first集合,由於終結符的first集合就是它自己,所以求出非終結符的first集合後,就可很直觀地得到每個字串的first集合。1.直接收取 對形如u a 的產生式 其中a是終結符 把a收入到f...