LALR(1)語法自動分析生成器Mathew
首次寫部落格,文采不好大家不要見笑額。
簡介:
Mathew(馬修),馬脩名字源於《魔力女管家》裡的星神馬修。馬修是一個LALR(1)型活動板房式的語法自動分析生成器。馬修繼承了Lemon,也許大家對LEX和YACC比較熟悉。這兩個工具配合使用可以輕鬆地構造出非常複雜的詞法和語法分析程式。 Lemon類似於YACC,它是一個C或者C++語言的LALR(1)語法分析器生成器,其內部模板檔案的思想成為了馬修支援更多語言平臺的啟發。馬修目前提供了c/c++, c#, java的語言模板檔案。如果想使用其它語言,只需要拿其它語言模板檔案(.tpl檔案)依樣畫葫蘆地修改一下就可以了,模板檔案的思想避免了為適應相應相應平臺的語言而去修改馬修的原始碼,也就是不需要重新編譯馬修。如果某些語言比較特殊需要修改原始碼,可以在GitHub下載馬修原始碼。由於篇幅有限馬修的特性在這裡就交給了原始碼內部的說明文件來向大家解釋。
簡易計算器的實現:
下面就利用一個簡單的計算器的實現來簡單的說明一下馬修的用途。計算器程式是所有關於語法分析書籍裡最喜歡提及的例子也就是相當於程式設計語言的第一課Hellow World!。
這裡拿C#語言的計算器例子來演示一下:
1.首先在github下把C#這個資料夾下載下來。
開啟後有如下幾個檔案
這裡面最重要的就是gram.y語法檔案和template.tpl(相應的語言平臺的模板檔案)。
template.tpl:
模板檔案可以彈性修改為相應語言版本,模板檔案的鍵值對採用了紅黑樹結構儲存,所以上面%號的鍵值對之間的順序還是可以打亂的。當然馬修原始碼包目前就提供了三大程式語言的支援。我們平時要寫的就是語法檔案gram.y:
/* simple calculator */
%include{ using System.IO; using System.Collections.Generic; //#define DEBUG }
%token_type <int> %nonterminal_type <int> %left PLUS MINUS. %left DIVIDE TIMES. %syntax_error{ Console.WriteLine("Syntax Error! \n By Shift " + @@ + " value(" + $$ + ")"); }
%parse_failed{ Console.WriteLine("Parse Failed!"); Environment.Exit(0); }
program -> expr($A).{ Console.WriteLine("Result = " + $A); }
expr($A) -> expr($B) PLUS expr($C).{ $A = $B + $C; }
expr($A) -> expr($B) MINUS expr($C).{ $A = $B - $C; }
expr($A) -> expr($B) TIMES expr($C).{ $A = $B * $C; }
expr($A) -> expr($B) DIVIDE expr($C).{ if($C != 0) $A = $B / $C; else Console.WriteLine("Divide by zero!"); }
expr($A) -> INTEGER($B).{$A = $B;}
%code{ public static void Main(string[] args) { Object pParser = ParseAlloc(); Parse(pParser,INTEGER,5); Parse(pParser,PLUS,0); Parse(pParser,INTEGER,6); Parse(pParser,TIMES,0); Parse(pParser,INTEGER,3); Parse(pParser,0,0); ParseFree(pParser); Console.ReadKey(); } } 然後點選上面那個ruan2.bat批處理檔案執行並生成yy_table.cs。
不報錯就表示成功了!
yy_table.cs就是我們想要的結果了。
將上述生成的程式碼直接複製貼上覆蓋掉控制檯原來的程式碼就可以直接運行了,如果不想在控制檯上實現可以修改語法檔案或嘗試修改一下模板檔案讓平臺適應性更強。這個C#計算器例子很簡單僅僅只是實現了加減乘除四則運算,上述程式碼實現了5+6*3 結果是輸出23。
java平臺
馬修是一個很實用的工具,不僅可以生成語法分析程式,還可以選擇性的生成狀態轉換表,編譯原理課程上寫出相應的產生式並以利用馬修生成狀態轉換表來驗證使用鉛筆的推導。這個表在哪呢,就是上面給大家列出的gram.out檔案,這個檔案是生成yy_table.cs的同時生成的。用記事本就可以直接打開了。
如果你有足夠的心思,可以利用它實現自己的一門計算機語言!