編譯原理之自頂向下分析

2021-03-31 22:08:44 字數 1325 閱讀 3695

編譯原理之自頂向下分析(daywolf原創)

自頂向下分析演算法通過最左推導中描敘出各個步驟來分析記號串輸入,一般用遞迴下降分析和ll(1)分析。其中ll(1)分析表示從左向右地處理輸入,它為輸入串描述乙個最左推導,只用乙個符號來**分析的方向。現在在一般的程式裡都是使用ll(1)分析方法,我們在這裡就只介紹ll(1)。

ll(1)由於並沒有使用遞迴的方法,所以必須使用分析棧。這裡有乙個問題不知道大家有沒有注意?棧究竟用幾個才是適合呢?如果是ll(1)的話就應該使用乙個,如果是ll(2)的話就應該使用兩個,如此類推。我們先介紹自頂向下方法中的兩個動作,第乙個是生成,英文是generate,第二個是匹配。我們這裡不作任何的解釋,實際行動最重要,哈哈。好,請看下面的例子。

有乙個簡單的文法:s->as|b,其中e標識為空

分析棧  輸入  動作

1 $               ab$             生成s->as

2       $sa             ab$             匹配

3       $s              b$              生成s->b

4       $b              b$              匹配

5       $               $               接收

看到了沒有,是不是很簡單呢?解釋一下,分析棧要先放進乙個$符號標識結束,生成了之後要把內容以相反的方向壓進棧。

由於左遞迴是很難做出演算法的,下面我們來看看用ll(1)是怎樣消除左遞迴的。什麼?不知道左遞迴是什麼。好吧,讓我告訴你,例如有這樣的文法a->aa|b,你看一下會生成什麼b,ba,baa,baaa....當然還有更複雜的,不用急下面會慢慢介紹。這個簡單的左遞迴可以轉化為右遞迴

a -> ba'

a'-> aa'|e

上面的是簡單的直接左遞迴,當然還有普遍的直接左遞迴,文法為a->aa1|aa2|...|b1|b2

轉化為a ->  b1a'|b2a'|...bma'

a'->  a1a'|a2a'|...|e

還有一般的左遞迴,是指不帶e產生式且不帶有迴圈的文法,由於一般程式設計中不會出現在這裡就不作介紹了。如果想再學習可以參principles and practice一書。

你有沒有發現我們只說了左遞迴的情況,那右遞迴又有沒有什麼消除方法呢?答案是有的。例如下面的乙個例子是如下:a->ab|ar

很明顯,ll(1)分析方法不能區分這種情況中的產生式選擇。這種簡單揭發式將左邊的a分解出來,我們稱為提取左因子,結果如下。

a ->aa'

a'->b|r

哇,我介紹了很多啦,有沒有什麼獎勵啦?哈哈。其他就要自己動手咯。

編譯原理 自頂向下分析

從頂部的根節點到底部的葉節點分析方法叫做自頂向下分析。我們知道頂部的根節點可以表示成乙個文法的開始符號s,所以說,自頂向下分析可以看成是從文法的開始符號s推導出詞串w的過程。例如,我們以輸入id id id 為例分析自頂向下的分析方法。首先從開始符號e 也就是樹的根節點 開始推導。首先用第乙個產生式...

編譯原理 自頂向下語法分析

對於任何輸入串,從文法開始符號 根節點 出發,自上而下,從左到右地為輸入串建立語法分析樹。簡而言之,就是尋找輸入串的最左推導的過程。之前我們了解到,一旦有左遞迴存在便無法構建這樣的語法樹,所以用自頂向下語法分析必須先去除左遞迴。同樣,由於使用最左推導,也不能處理有複雜回溯的輸入串。自頂向下的語法分析...

編譯原理 自頂向下分析中FIRST集的計算

的first集,即first 被定義為 可從 推導得到的串的首符號的集合,其中 是任意的文法符號串。如果 經過若干步的推導得到乙個 那麼 也在first 中。比如 a c a可以推導出c 這個串,這個串的首符號為c,因此c在first a 中。e te e可以推導出 te,而 te的首符號為 並且e...