編譯原理之語法分析 自下而上分析 一

2022-08-30 00:42:15 字數 3222 閱讀 6639

從名字很容易看出來,自下而上分析法對應的就是自上而下分析法,這裡我首先簡單區分一下這兩種分析方法的區別。

自上而下分析法是多個推導的過程,而自下而上分析法是多個歸約的過程。那麼歸約和推導又是什麼呢?下面通過乙個簡單的例子說明。

例如有乙個文法g(s) :  ①s -> aacb ,②b->b,假如有乙個輸入符號串為aacb。說明:g(s)中的s說明s是開始符號。

推導(從開始符號開始):第一步:s->aacb,第二步:b->b。

經過兩步之後我們就能推到出輸入符號串aacb。而第一步中我們從s推出aacb的過程就是推到的過程,同理第二步中b推出b也是推到的過程。

歸約(從輸入符號串開始):第一步:aacb中的b歸約為b,第二步:aacb歸約為s。

經過兩步之後我們將輸入符號串aacb中的b根據②中的規則替換(歸約)為b,這時輸入符號串從aacb變為aacb,然後再根據規則①將aacb歸約為s。

通過這個例子我們可以總結一句話:推導的過程就是從某個產生式的左部(s)推導出右部(aacb)的過程。歸約的過程是從某個產生式的右部(aacb)歸約(替換)為左部(s)的過程。

多個推導的過程能夠組成自上而下分析即從開始符號到輸入符號串的過程,多個歸約的過程能夠組成自下而上分析即從輸入符號串到開始符號的過程。

(一)什麼是自下而上分析法

自下而上分析法定義:從輸入串開始,逐步進行歸約,直至文法的開始符號。

在自下而上分析法中使用的方法(移進-歸約法):使用乙個符號棧,把輸入符號逐一移進棧,當棧頂形成某個產生式右部時,則將棧頂的這一部分替換(歸約)成該產生式的左部符號。(下圖就是乙個移進-歸約的例子)。

符號棧方式展示移-進歸約法

從圖中可以發現移進-歸約法就是將輸入符號串(從左到右)依次讀入,每讀入乙個字元就和所有產生式的右部對比,檢視是否能歸約為產生式左部。(即圖中符號棧最後三個狀態),讀入b時和產生式②對比可歸約為b,此時符號棧變為aacb,又和產生式①對比可歸約為s。

2.分析樹方式展示移-進歸約法

從分析樹中,從根節點到葉子節點就是自上而下分析法,從葉子節點逆推到根節點就是自下而上分析法。

(二)自下而上分析法之短語、直接短語、控制代碼

上邊我們簡單了解了一下什麼時自上而下分析法,下邊我們在說明如何進行歸約前先搞清楚幾個定義(短語、直接短語、控制代碼)。 直接上圖給出這三個比較標準的定義。

下邊通過分析樹中的文法對這三個定義進行分析(以下為個人見解)。

給出文法(如下圖)求句型aabcde的短語、直接短語、控制代碼。(畫出從s推導出aabcde的分析樹)

短語:在分析樹中,所有父節點的最終葉子節點組成的集合。

例如:根節點s,它直接指向的節點為aacbe,但是a和b還有子節點,因此a和b就不是根節點s的最終葉子節點。應該將a->ab,然後b->d。最終得出aabcde是關於s的短語。

父節點a,它直接指向的節點為ab,而a和b均為葉子節點,因此ab就是關於a的短語。

父節點b,它直接指向的節點為d,而d為葉子節點,因此d是關於b的短語。

直接短語:只需要一步轉換的短語稱為直接短語。

例如:父節點 a,a->ab可一步推導出,因此ab屬於直接短語。

父節點b,b->d可一步推導出,因此d屬於直接短語。

根節點s,因為s->aabcde不能一步推導出來,還需要將a->ab,b->b,因此aabcde就不屬於直接短語。

控制代碼:分析樹中最左側的直接短語。如上圖中直接短語ab位於最左側,而直接短語d在ab的右邊,所以ab是控制代碼。

注意:具有二義性文法的控制代碼可能不唯一。例如:文法g(e):  e-> e+e | e*e | (e) | i ,給出句型e+e*e的控制代碼。

(1)e -> e+e -> e+e*e> 控制代碼為e*e

(2)e -> e*e ->e+e*e  控制代碼為e+e

(三)規範歸約

規範歸約定義:將控制代碼替換成相應產生式左部符號而得到的,則該序列是乙個規範歸約。最左歸約的過程就是不斷將控制代碼轉換成產生式左部(每歸約一次句型的控制代碼就變化一次)。

例如上圖中規範規約的過程:

①控制代碼為b,根據a->b,將控制代碼b(左側的b)歸約為a,此時控制代碼變為ab。

②控制代碼為ab,根據a->ab,將控制代碼ab歸約為a,此時控制代碼為d。

③控制代碼為d,根據b->d,將控制代碼d歸約為b,此時控制代碼為aacbe。

④控制代碼為aacbe,根據s->aacbe,將控制代碼aacbe歸約為s,最左推導過程結束。

其實最左推導的過程就是「剪枝"的過程,①將b節點剪去,②將ab節點剪去,③將d節點剪去,④將aacbe剪去,最終只剩下s節點。

規範歸約的基本問題:

1、如何找出或確定可歸約串——控制代碼?

2、對找出的可歸約串——控制代碼替換為哪一非終結符號?

基於上述兩個問題,實現移進-歸約分析的乙個方便途徑是用乙個棧和乙個輸入緩衝區,用#表示棧底和輸入的結束。

對於棧和輸入緩衝區的使用可嘗試推導下圖中的例子,由於例子較為複雜,篇幅有限這裡不做詳細詳解。

對於語法分析的操作(即上圖中的動作)共有四種狀態:

1、移進:下一輸入符號移進棧頂,指標(讀頭)後移。

2、歸約:檢查棧頂若干符號能否進行歸約,若能,就以產生式左部代替該符號串,同時輸出產生式編號。

3、接受:移進-歸約的結局是站內只剩下棧底符號和文法開始符號,(指標)讀頭也指向語句的結束符。

4、出錯:發現了乙個語法錯誤,調出出錯處理程式。(可歸約串一定處於棧頂位置,而不可能出現在棧頂的下方,因為一旦出現可歸約串就會及時將其歸約掉,不會出現棧頂有歸約串而繼續讀入符號的情況)。

以上均為個人學習總結,如有錯誤或異議歡迎提出(自下而上分析法未完待續......)。

編譯原理語法分析 自下而上分析

規範規約 短語 令g是乙個文法,s是文法的開始符號,假定是 文法g的乙個句型其中 vn vt a vn 如果有 s a 且a 則 稱是句型 相對於非終結符a的短語 直接短語 特別是,如果有a 則稱 是句型 相對於規則a 的直接短語 控制代碼 乙個句型的最左直接短語稱為該句型的控制代碼 規範歸約是關於...

自下而上語法分析

1.已知文法 e e t t t t f f f e i 以控制代碼作為可歸約串,寫出符號串 i i i 的 移進 歸約 分析過程。答 符號串 i i i 的 移進 歸約 分析過程為 符號棧輸入串動作 i i i 移進 i i i 歸約 f i i 歸約 t i i 歸約 e i i 移進 e i ...

自下而上語法分析

1.已知文法 e e t t t t f f f e i 以控制代碼作為可歸約串,寫出符號串 i i i 的 移進 歸約 分析過程。符號棧輸入串動作 i i i 移進 i i i 歸約 f i i 歸約 t i i 歸約 e i i 移進 e i i 移進 e i i 歸約 e f i 歸約 e t...