Flex應用實例:
1) 從標准輸入中逐行讀取待檢驗的字符串。使用正則表達式匹配 IPv4 地址,若匹配失敗則輸出 Invalid ,若匹配成功則輸出 IPv4 地址的類別。
2) 從標准輸入中讀取 DOT 文件,文件無詞法、語法錯誤。
根據 token.txt 使用正則表達式匹配 token 並且輸出。
Flex 中必須使用 C 代碼,無需自定義 main 、 yywarp 函數, gcc編譯時添加 -lf 或者 -ll 選項即可自動鏈接這些函數。
DOT 關鍵詞大小寫不敏感。
DOT 只包含英文字母和符號,即在 ASCII 范圍內。
DOT 的 ID 與 C 語言相同, STRING 里面可包含轉義的雙引號,即 \" 。
相關參考資料:http://lesliezhu.github.io/public/flex.html
相關代碼和輸入輸出文件:https://github.com/sysuKinthon/Compile/tree/master/FLEX
Bison應用實例:
使用Flex、Bison解釋正則表達式,以文本方式輸出其語法結構。
例子
主要參考資料:http://epaperpress.com/lexandyacc/
相關代碼和輸入輸出文件:https://github.com/sysuKinthon/Compile/tree/master/Bison
體會:這個主要是理解如何去構建一個沒有二義性的產生式來解決正則的匹配問題,以下對產生式說明下:
對於產生式的構建:
a)一個規則單元盡量不要使用exp:exp exp的形式,而要使用左遞歸的形式,比如上圖中的concat產生式;
b)為了防止規約/規約沖突,將規則(不同的非終結符的語法規則)按照自上而下(規約的頂層為上)的順序排列,上面的規則會代先,也就是說在我們的文法中我們就定義好我們的優先級。
可以借鑒:
我們以ab|cd這個輸入來說明,其輸出應該為Alt(Cat(Lit(a), Lit(b)), Cat(Lit(c), Lit(d))),是怎么運行的
首先yyparse調用yylex得到一個Lit類型的token,其匹配到了single:Lit這個產生式,產生的single又匹配了bracket:single,同理將會發生exp:bracket, concat:exp的匹配,到這里,發生的規約與移入沖突,也就是alt:concat要求規約,concat:concat exp要求移入(編譯是向前看一步的,b可以規約到exp,所以提示要移入),在Bison中在規約與移入沖突中的優先移入的;所以就會發生b的token移入,同時到達concat:concat exp后就會規約到一個concat,接下來再到alt:concat后,alt:alt "|" concat提示要移入。所以最后就會產生Alt(Cat(Lit(a), Lit(b)), Cat(Lit(c), Lit(d)))這樣的一棵語法樹(語法樹的文本型需要根據自己構建的語法樹來生成)