1 系列說明
2 語法分析說明
語法:組合單詞以形成詞組、從句或句子的方法。
經過詞法分析,我們已經可以將輸入文本識別成一個個的單詞,本階段的目標是將這些單詞識別成句子,判斷單詞的這種組合形式是否符合我們定義的語法。
2.1 用文法來定義語法
語法分析需要由遞歸而獲得的額外表示能力,顯然正則表達式已經不能滿足我們的需求。
事實上,文法也可以用來描述詞法單詞的結構,但正則表達式已經可以滿足需求,這時使用正則表達式更為簡潔。
2.2 LR (1) 分析法
@%……¥&%#¥太複雜不想說
總之,LR (1) 是一種非常非常強大的分析算法,能夠解決很多歸約 - 歸約衝突,大多數用上下文無關文法描述其語法的程式設計語言都有一個 LR (1) 文法。
2.3 使用 Yacc 生成語法分析器
構造 LR (1) 分析表的演算法簡單得足以用電腦來自動完成,而且手工構造十分麻煩無趣,所以使用 Yacc 是一個明智的決定。
類似 Lex,Yacc 規範分為三部分
第一部分同 Lex,包含 include 和聲明
第二部分定義從詞法分析中接收的終結符,開始符號,優先級等
第三部分定義文法及語義動作,語法分析階段只定義文法,語義動作到語義分析時候再完成。
2.3.1 衝突
Yacc 選擇移近來解決移進 - 歸約衝突,選擇使用在文法中先出現的規則來解決歸約 - 歸約衝突。
2.3.2 優先級指導
定義優先級是為了解決二義性,這樣寫文法的時候方便得多。
Yacc 在第二部分可以假如優先級指導命令
自上而下優先級降低,left right 說明單詞是左結合還是右結合。
3 具體實現
語法分析器和改進過的詞法分析器源碼見文章開頭。
進行到本階段,編譯器發展為四個模組:
1. 錯誤處理模組(errormsg.c errormsg.h):用來產生含文件名和行號的報錯信息
2. 常用工具模組(util.c util.h):定義一些常用的函數
3. 詞法分析模組(simplec.lex):通過 Lex 進行詞法分析
4. 語法分析模組(simplec.yacc):通過 Yacc 進行語法分析
其中上一階段的 token.h 已經不再需要,作為代替,Yacc 會根據我們寫的文法的單詞規範自動生成一個與單詞相關的頭文件 y.tab.h ;parsetest.c 是一個驅動程式,正常情況下會輸出 Parsing successful!
附:ANSI C grammar (Lex) ANSI C grammar (Yacc)
語法分析 Done.