如何構建一個語法分析器?


實驗一要求構建一個詞法分析器。詞法分析器的構建過程比較簡單。
由於是給定的詞法,所以我們只要能夠構造出狀態圖,將再將DFA轉化為NFA,然后只用最朴素的case或者ifelse就可以完成。
當然,如果你考慮到使用緩沖區解決代碼長度問題等等也是很棒的。
實驗二要求構造一個語法分析器。語法分析器相對於詞法分析器顯得復雜很多。龍書上給出了基本所有的偽代碼。
馬上就到deadline,所以,我想將自己的構建過程和大家分享一下。
由於當初是選擇MATLAB語言作為載體,所以大家可能沒有辦法直接copy我的代碼。不過,MATLAB代碼很直觀,大家完全可以仿照寫出自己的代碼。
本博文僅僅是為大家實驗二的設計提供一個整體的思路,如果有不足的地方,還請指正。
寫在前面:
1.大家不要把自己嚇壞了!這個語法分析器並不是很難。
2.老師檢查並不是要求我們做的完美。主要是希望我們能夠體驗這個語法分析的全過程。
3.主要難度在於如何構建一個合理的數據結構來貫穿整個始終。
4.如果大家對整個語法分析器還一頭霧水,那強烈建議大家去復習一遍第四章的知識點。

選擇很多:
語法分析器的功能如果想要足夠強大,那么需要的模塊就顯得非常多。但是,如果你的語法分析器僅僅只是為了通過實驗二的測試,那么我可以告訴你,肯定很輕松就可以。因為即使你的語法分析器不能正常工作,只要你能夠將過程解釋清晰,老師並不會為難大家。為了比較完整的敘述,我會將我所涉及的部分按照邏輯順序展開。最后會告訴大家如何做出合理的選擇以通過實驗二測試。

思路整理:根據書本P167圖4-40的算法,我們知道,如果要構造一個語法分析器(LR(1)),我們需要構造一個ACTION和GOTO表。這兩張表格的構造,需要我們構造一個函數,這個函數可以試驗閉包的計算,也就是CLOSURE這個函數。而構建CLOSURE這個函數的過程中,需要使用到一個很重要的子函數去求解FIRST集合。因此,我們還需要構造一個函數進行FIRST集合的求解。因此,我們主要分為以下幾步:
1.構造FIRST函數
2.構造CLOUSRE函數
3.構造LR(1)項集
4.通過LR(1)項集構造ACTION & GOTO 表
5.運用P160圖4-36算法實現語法分析程序

接下來會比較枯燥,大家可以不需要一口氣寫完。,每天完成一些步驟就可以了。當初我也是摸着石子過河。第一次花了兩個星期,結果滿是bug。然后實在不滿意,寫了一遍,又花了一個星期,才完成的。

1.構造FIRST函數
FIRST函數的構造,書上沒有偽代碼,但是給出了文字解釋,在P140頁。
在FIRST集合的求解過程中,很重要的一點就是如何進行空產生式的推導。
為此,大家可以單獨構造一個函數實現空產生式的推倒。
在求解FIRST集合時,是不允許文法存在左遞歸的。如果存在左遞歸將會導致程序的無限循環。
我們的文法可能並不一樣。所以這里大家可以有多種處理方式:

  1. 如果你的文法沒有左遞歸,那么直接忽略這步。
  2. 如果你的文存在左遞歸,但是你有不想多寫太多的函數,那么,你可以選擇直接進行手動消除,然后在輸入。
  3. 如果你想讓你的編譯器可以處理各種文法,而不是僅僅局限於實驗二,那么,你需要花比較多的時間另寫一個模塊實現左遞歸的消除。其中包括直接左遞歸與間接左遞歸。
    4.如果你既不想手動推導也不想編寫程序,那么只需要才FIRST集合推導的過程中加入循環次數的限制,一般也是ok的。
    我采用的是思路3 。在消除間接左遞歸時,我們需要另外寫一個函數進行環路判斷。具體的代碼我放在群里了。

2.構造CLOSURE函數
其實只要有了FIRST函數,這個函數的構造顯得十分簡單。我們需要做的就是設計一個良好的結構體來按部就班的實現書上的代碼。

3..構造LR(1)項集
LR(1)項集的構造也是書上算法的直接實現。

4.通過LR(1)項集構造ACTION & GOTO 表
在得到LR(1)項集后,我們通過遍歷項集中的每一個閉包,就可以構造出分析表。這個過程在P167算法4.56有詳細描述。

5.運用P160圖4-36算法實現語法分析程序
這只是簡單的ifelse分支操作。並不復雜。我們要構建兩個棧,符號棧和狀態棧。在進行出棧入棧時,時刻保持棧頂高度一致。

寫在后面:
由於期末時間比較緊缺,寫的比較粗糙,望諒解。
我把代碼和我的測試用例都上傳到群文件了。同時我還上傳了一份使用java和c#混合編寫的代碼,供大家參考。
詭異一笑:
如果大家實在來不及,可以選擇手動生成ACTION和GOTO表格,然后直接進入第5步。(然而,事實告訴我這么做是很不好的。)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM