flex與bison是編譯器設計工具。這裏的編譯器爲廣義,其中包括通常的編譯器、腳本解析器等,須要進行語言結構解析來得出意義的程序。正則表達式
當咱們須要用一個語言來設計一款編譯器時,須要考慮太多設計重心外的東西,如內存管理、模塊設計、字符識別等,flex與bison就很好地爲咱們處理了這些事情,將設計重心放在詞法與語法分析上。函數
flex提供詞法分析,採用的是正則表達式匹配字符。工具
bison提供語法分析,採用A : B | C ;的方式進行語法設計。flex
具體的規則《flex 與 bison》有很詳細的描述。spa
首先,對於語言的解析,是以流(stream)的方式進行的。設計
假定咱們詞法與語法都已經設定好指針
if A > B then C = 0;內存
對於以上句子大概會進行如此解析:編譯器
1. if 詞法分析斷定爲 IF,返回標記內存管理
2. 語法分析接到標記,存放到棧內,發現找不到適合的語法來進行歸約,返回進行詞法分析
3. A 詞法分析斷定爲NAME,返回標記
4. 語法分析接到標記,存放到棧內發現NAME能被歸約成exp,NAME出棧,exp入棧
5. 如今棧內有IF exp,語法分析發現找不到適合的語法來進行歸約,返回進行詞法分析
6. > 詞法分析斷定爲CMP,返回標記
7. 語法分析接到標記,存放到棧內,發現找不到適合的語法來進行歸約,返回進行詞法分析
8. B 詞法分析斷定爲NAME,返回標記
9. 語法分析接到標記,存放到棧內發現NAME能被歸約成exp,NAME出棧,exp入棧
10.語法分析接到標記,存放到棧內,發現棧內有exp CMP exp,能夠規約爲exp,因而進行歸約,exp放回棧內,而後發現有IF exp,沒法歸約,返回詞法分析
...
*分析方法採用的是lrlr(1),這也是bison的通常作法,上面分析爲了方便省去向前查看的步驟。
上述例子能夠看出只要過一遍字符流,經過詞法分析與語法分析的交替進行,就能夠最終歸約句子。
爲了方便維護,語法分析時都會進行語法樹構建,如上述例子:
當NAME被歸約成exp時,建立節點,節點須要保存NAME所在符號表的位置,
當exp CMP exp被歸約成exp時,建立節點,節點須要保存做exp節點的指針爲左子樹,保持右exp節點的指針爲右子樹,保存CMP類型
通常的編譯器都可以自定義變量,如上述例子的A、B、C,這些符號會在詞法分析時被判別爲自定義變量。
自定義變量須要進行維護,能夠用哈希表保存自定義變量。
自定義變量的名稱在詞法分析時,就能夠加到哈希表內。
另外自定義變量包含比較多的信息,如類型、變量值等,若是是函數,那麼還會包含函數體指針,這些在詞法分析時是沒法獲得的。而在詞法分析時,只是構建語法樹,並不適於進行信息填充。可是在計算時就會用到哈希表內的變量。
假設句子是一行一行執行的,那麼在碰到'\n'符合時就會執行計算,
如上例:C = 0;
計算時會把C在哈希表內的變量值填充爲0;