s->ab
a->a|b|e
b->b|e
e為空符號,大寫字母為非終結符,小寫字母為終結符
first集合求法
因為b能推導出兩個終結符,所以它的first集合比較容易求出來
1.若x->a,x->b,x->c,則將終結符a加入first(x)中,即first(x)=
2.若x->e ,則將終結符e加入first(x)中
由上面步驟知例子中first(b)=
因為a有乙個非終結符b,且b的first集合已經知道了,所以判斷a
3.若x->bcd,先檢測到b,則先將first(b)中所有元素(除了空集)加入first(x),若first(b)中不存在空集, 即停止檢測,若存在則向b的後面檢視,將first(c)中所有元素(除了空集)加入first(x),再判斷first(c)中是否有e…直到最後,若d之前的所有非終結符的first集中都含有e,就檢測到d時,將first(d)也加入first(x),若first(d)中含有e,則將 e加入first(x)
由上面的步驟,例子中first(a)=ufirst(b)u=
最後,例子中first(s)=(first(a)-)u=
如果文法改為s->ab,則first(s)=(first(a)-)ufirst(b)
follow集合求法
首先看到開始符號s,發現它沒有在任何乙個產生式的右部出現
1.對文法開始符號s,置#於follow(s)中
則follow(s)=
再看例子中的非終結符a,它出現在第乙個產生式的右部,後面乙個是b,所以follow(a)=
2.對於產生式:a->abc,將除去空集e的first(c)加入follow(b)中
3.對於產生式:a->ab或者a->abc,(其中c可以推導出空串,c=>*e),則將follow(a)加入follow(b)中
所以對於例子的非終結符b來說,它出現在第二個產生式的右部,即相當於a->b,根據步驟,將follow(a)加入到follow(b)當中,即follow(b)=follow(a)=
如果將例子的第乙個產生式改為s->ab,則follow(a)=first(b)-=
ll(1)文法判斷
對於例子來說
首先判斷該文法不含左遞迴
由於first(a)n follow(a)=不為空集,所以該文法不是ll(1)文法
判斷乙個文法不是ll(1)文法只要乙個條件不滿足就可以判斷
s->abc
a->a|e
b->b|e
求解過程就簡約點了
first(a)=
first(b)=
first(s)=(first(a)-)u(first(b)-)u=
follow(s)=
follow(a)=(first(b)-)u=
follow(b)=
由於first(a) n follow(a)=空集,first(b) n follow(b)=空集
且first(a) n first(e)=空集,first(b) n first(e)=空集
所以這個文法是ll(1)文法。
怎麼求 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集 和 SELECT集
first a 為a的開始符或者首符號集。設g vt,vn,s,p 是上下文無關文法 first 特別的,若 能推導出 則規定 first 若x vt,則first x 簡單講,終結符的first集就是它本身 若x vn,且有產生式x a a vt,則 a first x x 則 first x 簡...
C 實現first集follow集
1.代替字元 2.同一非終結符如有多條產生式必須寫成一行,中間用 分隔,不允許有空格 存在很多問題,大量 非正常 情況都未考慮,謹慎參考 include include include includeusing namespace std struct exp vectorv 產生式集合 strin...