1. 程式人生 > >編譯原理中的語法分析——自頂向下

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

語法分析——自頂向下

語法分析在編譯原理的:
這裡寫圖片描述

語法分析分為自頂向下自下而上

自頂向下:(就是從文法的句子可以歸約出開始符,簡單的說就是從一個語法樹的底部推出語法樹的根)

自下而上:(就是從文法的開始符推出文法的句子,簡單的說就是從一棵語法樹的根推出語法樹的葉子結點)

現在我們先來討論自頂向下,自頂向下語法分析的文法應該構造成什麼樣子呢?
LL(1)文法
那構造LL(1)文法的條件是什麼呢?,首先來看看自頂向下會出現的問題

1.產生文法的左遞迴,左遞迴會帶來什麼壞處呢?

陷入死迴圈
就如
這裡寫圖片描述
因為建立一個語法樹是從左往右建立,這樣文法的左部就會一直伸長,二次文法的句子得不到匹配就會陷入死迴圈。(可怕ヽ(*。>Д<)o゜)。
消除文法的左遞迴的方法:
這裡寫圖片描述


修改後的一般格式:
這裡寫圖片描述

通式:
這裡寫圖片描述
其中,每個a都不等於空,每個B都不以P開頭,修改後的文法形如:
這裡寫圖片描述

2.文法的回溯,這個又會導致什麼問題呢?

這個會影響語法分析程式的效率。我們只需要提取左因子即可:
這裡寫圖片描述
這樣我們得到的文法就是不產生左遞迴和回溯的文法了,我們要自頂向下語法分析就得產生一個LL(1)文法,那麼LL(1)文法怎麼定義呢?這裡寫圖片描述

首先思考怎麼產生first集和follow集呢?

書上其實講得我頭暈腦脹,呵呵,所謂得專家就是挨板磚的傢伙,你永遠也get不到他要講什麼。所以我就通俗的以我的理解給大家講講。
這裡寫圖片描述

如上文法:

first集

先看E的first集,很明顯,如果E的最左邊開始就有終結符了,那麼這個終結符就是E的first集,如果沒有那也沒有關係,就看T,就將T推匯出的第一個最左終結符視為E的first集,可能這時候有人就會問了如果T為空怎麼辦呢?那麼你就接著看下一個非終結符就行了,將下一個非終結符推匯出的最左終結符算作E的first集,如果T和E’都為空怎麼辦呢?那就直接把E的first集寫為空就可以了,E’的first集就可以簡單的得出是+和空了,T可以見E同理可得,T’見E’同理可得,F的first集就為(和i
:
這裡寫圖片描述

follow集(切記follow中永遠都沒有空)

E->TE’
看E可以將E的follow加入E’的follow,(A->aBb或者A->aB,如果在A->aBb中,b為空,那麼A的follow集可以加入B的follow集中,這裡我們將a視為T,將E’視為B)。
E的follow也可以加入到T的follow集中E’可以為空,根據第二個產生式所述,我們可以將E視為A,將a視為空,將T視為B,將E’視為b,b這裡是空。
因為產生式E->TE’,說明E’在T的後面我們就可以把E’的first集加入到T的follow集中。

E’->+TE’|空
這樣我們可以得到E’的follow集可以是E’的follow集(屁話,形式一下)E’的follow集加入到T的follow集,因為E’為空,(左邊)E’視為A,+視為a,T視為B,(右邊)E’視為b,(A->aBb或者A->aB,如果在A->aBb中,b為空,那麼A的follow集可以加入B的follow集中,這裡我們將a視為T,將E’視為B)。
因為產生式E’->TE’,說明E’在T的後面我們就可以把E’的first集加入到T的follow集中。

T->FT’ 同E->TE’可得

T’->*FT’|空 同E’->+TE’|空,可得

F->(E)|i
說明E的follow集應該加入)
這裡寫圖片描述

關於

語法分析程式

有兩種

遞迴下降分析程式

預測分析程式

遞迴下降分析程式,是體現的計算思維的自動化。

由於語法在定義的時候,文法單位之間的定義是相互的引用甚至可能形成巢狀,子程式之間可能形成相互呼叫或者遞迴呼叫。通過子程式之間的相互呼叫來實現對輸入串的識別,這樣的分析程式叫做遞迴下降分析程式,主要是因為文法分析程式的遞迴呼叫。

預測分析程式,是體現的計算思維的知識與控制的分離(好處將來可以自動的產生預測分析程式,只要針對任何一個LL(1)文法自動的產生一個分析表綁上一個通用的總控程式,就可以得到一個LL(1)文法的預測分析程式)。

關於其分析表的建立,是將所有元素的first集和follow集出空以外的元素寫在那一橫行,每一列寫不同的非終結符,這個非終結符的first集就寫這個非終結符推匯出來的產生式,如果非終結符推匯出來了空,就將非終結符產生出來的空寫在follow集元素的下面。

自頂向下語法分析大致就是這樣的了,我快沒有時間了,只能給大家初略的講講

此文章是根據聽了國防科技大學的老師和我們學校的老師講課所寫