對於非終結符號a,follow(a)被定義為:可能在某些句型中緊跟在a右邊的終結符號的集合(為什麼說是可能?因為在一些推導出來的文法符號串中,該非終結符號a可能在最右邊,比如:a—>+ta)。
如果存在s=>αaaβ(推導若干次)這樣的推導,終結符號a就在follow(a)中,其中α和β是文法符號串。
如果a和a之間存在一些文法符號,這樣的話這些符號會推導得到ε並消失。
另外,如果a是某些句型的最右符號,那麼$也在follow(a)中。
計算所有非終結符號a的follow(a)集合時,應不斷應用下面的規則,知道再沒有新的終結符號可以被加入到任意follow集合中為止。
1)將$放到follow(s)中,其中s是開始符號,而$是輸入右端的結束標記
2)如果存在乙個產生式a—>αbβ,那麼first(β)中除了ε之外的所有符號都在follow(b)中
3)如果存在乙個產生式a—>αb,或存在產生式a—>αbβ且first(β)包含ε,那麼follow(a)中的所有符號都在follow(b)中(同時follow(b)中也有follow(a)的所有符號)。
我們給出乙個文法g(e):
①e → te』
②e』 → +te』
③e』 →ε
④t → f t』
⑤t』 → *f t』
⑥t』 →ε
⑦f → (e)
⑧f → id
左側非終結符號分別為:e、e』、t、t』、f
我們先給出他們的first集:
nfirst(n)ee』
tt』f
我們先來看e,我們發現e在第⑦條產生式中出現,
e的後跟符號為 ),並且e為開始符號,因此 :
nfollow(n)e
我們再來看e』,該非終結符號出現在①、②條產生式中,
我們先來看第①條:e → te』
此時,根據第3)條規則,follow(e』) u= follow(e),即:follow(e』) =
我們再來看第②條產生式:e』 → +te』 ,由於左側文法符號也是e』,而根據第3)條規則,follow(e』) u= follow(e』),沒有什麼實際的意義。綜上:
nfollow(n)e』
接著是t,t出現在①、②的產生式右側,而①、②兩條產生式中t的後跟符號都是e』 ,因此,根據第2)條規則:first(e』 )中除ε之外的所有符號都在follow(t)中。所以:
nfollow(n)t
但是根據第3)條規則,因為first(e』)中包含ε,所以follow(t)中也有follow(e)的元素,綜上:
nfollow(n)t
我們再來看t』,在右側的產生式中t』出現在第④、⑤條產生式中。
對於第④條產生式,我們可以根據第3)條規則可知:follow(t』) u= follow(t),
對於第⑤條產生式,我們可以得到:follow(t』) u= follow(t』),但這並沒有什麼意義。
因此:n
follow(n)t』
最後,我們來看f。
我們觀察第④、⑤條產生式:
對於第④條產生式,由第2)條規則可知:follow(f) u= first(t』 ),
nfollow(n)t』
同時,因為first(t』 )中包含ε,所以根據第3)條規則可知:follow(f) u= follow(t)
nfollow(n)t』
對於第⑤條產生式,與上面同理,沒有什麼意義。
綜上:n
follow(n)t』
現在我們得到了所有的follow集:
nfollow(n)ee』
tt』f
編譯原理 自頂向下分析
從頂部的根節點到底部的葉節點分析方法叫做自頂向下分析。我們知道頂部的根節點可以表示成乙個文法的開始符號s,所以說,自頂向下分析可以看成是從文法的開始符號s推導出詞串w的過程。例如,我們以輸入id id id 為例分析自頂向下的分析方法。首先從開始符號e 也就是樹的根節點 開始推導。首先用第乙個產生式...
編譯原理之自頂向下分析
編譯原理之自頂向下分析 daywolf原創 自頂向下分析演算法通過最左推導中描敘出各個步驟來分析記號串輸入,一般用遞迴下降分析和ll 1 分析。其中ll 1 分析表示從左向右地處理輸入,它為輸入串描述乙個最左推導,只用乙個符號來 分析的方向。現在在一般的程式裡都是使用ll 1 分析方法,我們在這裡就...
編譯原理 自頂向下語法分析
對於任何輸入串,從文法開始符號 根節點 出發,自上而下,從左到右地為輸入串建立語法分析樹。簡而言之,就是尋找輸入串的最左推導的過程。之前我們了解到,一旦有左遞迴存在便無法構建這樣的語法樹,所以用自頂向下語法分析必須先去除左遞迴。同樣,由於使用最左推導,也不能處理有複雜回溯的輸入串。自頂向下的語法分析...