[心得] Parser
所謂的Parser是將符合既定文法(Grammar)的文字轉換成結構化,有用資訊的
的工具,通常所有的編譯器(Compiler)都會先將原始的程式碼經過Parser轉為,
特定的資料結構,如分枝敘述,型別定義等等。
除了Compiler外善用Parser可以帶給你比Regular Expression更強功能的文字處理
,當然強大功能的背後相對的一定有更複雜的設定和使用方法。
其實最初是因為小弟因工作需要要寫一個自動文件產生的程式,首先要支援的是
對C/C++的source code 進行分析,然後產生Word/Html文件,一開始是想利用
Regular Expression配合Word Library COM來做但是發現C/C++語法真是該死的
複雜,只好從新翻書本看看以前混過的Compiler到底是如何處理soure code的,
並在網路上面找到了一個不錯的Free產品,在這邊分享一些心得。
(其實非常想號招有志同好一起開發這個案子,並以GPL方式發行基於最近工作
較為繁重,帶比較輕鬆時候我會好好研究一下目前網路上面的GPL社群選一個
合適的,再將雛形擺上去到時候有興趣的在一起研究學習:))
首先產品關網連結
http://www.devincook.com/goldparser/
進入官網後先別急的下載,假如對parser沒有概念請先在官網左邊瀏覽一下
列出的Concepts。
簡單說明一下相關概念
Token : 對Parser有意義的符號,比如C的關鍵字,字串等等。
Grammer(文法) : 定義了要分析的程式規則,定義Grammer其實只是定義兩種
規則,分別是Terminate和nonterminal,看一下下面
C#程式的例子
int a = 3;
這個敘述(statement)紅色部分就是terminate,而綠色部分就屬於nonternminate
,通常parser是用DFA Algorithm來解析出Token。簡單來說terminate就是明確
清晰的字串,而nonterminate必須依照前後token來決定。
運作方式
Grammar -> Gold Builder -> .gtc file
|
▽
parser engine --> parsed data
△
|
Language source code
各位請先下載C的Grammar
http://www.devincook.com/goldparser/grammars/index.htm
到Programming Language選ANSI C
接著下載Gold Builder
http://www.devincook.com/goldparser/builder/index.htm
一OS不同選擇,Windows上的Gold Builder就是第一個。
Gold Builder會分析Grammar產生出parser engine要用的table。
操作方式就開啟grammar檔案然後最下面的button一直按到不能按,然後
Toolbar上面倒數第二個Icon按下去就可以測試了。
接者請下載Engine,這邊假設要用C#在.NET Framework 1.1上面執行
http://www.devincook.com/goldparser/engine/cs-morozov/Morozov-GoldParser.zip
Engine的說明文件
http://www.devincook.com/goldparser/engine/cs-morozov/doc/index.html
Engine下載完了以後開一個Visual Studio的專案,然後reference到剛剛下載的
engine DLL檔案即可快樂的測試了。
大約說明一下用法,詳細說明還請參考說明檔案
建立Parser物件
1.建立Parser要使用的Grammar物件
FileStream fs = new FileStream(garmmarFileName,
FileMode.Open, FileAccess.Read);
BinaryRead reader = new BinaryReader(fs);
GoldParser.Grammar grammar = new GoldParser.Grammar(reader);
2.建立Parser物件
GoldParser.Parser parser = new GoldParser.Parser(sourceCode, grammar);
進行Parser
while (true)
{
ParseMessage response = parser.Parse();
switch (response)
{
case ParseMessage.LexicalError:
//處理token錯誤,比如int打成itn
//Do some thing 通常是丟出exception
break;
case ParseMessage.SyntaxError:
//語法錯誤比如少了';'
//Do some thing 通常是丟出exception
break;
case ParseMessage.Reduction:
//規則完成,在Grammar定意的規則符合,必須使用
//parser.CurrentReduction.Count來取得所有子規則繼續處理
break;
case ParseMessage.Accept:
//整個source code parse完畢
break;
case ParseMessage.TokenRead:
//讀取到token
break;
case ParseMessage.InternalError:
//內部錯誤
//Do some thing 通常是丟出exception
break;
case ParseMessage.NotLoadedError:
//讀取錯誤
//Do some thing 通常是丟出exception
break;
case ParseMessage.CommentError:
//定義的注解解析錯誤
//Do some thing 通常是丟出exception
break;
}
}
上面只是大概的架構,建議各位下面幾個Class都要看一下說明文件
Symbol
Token
Reduction
Rule
當然要不是我接觸到這個案子也不會想去研究這種東西,大部分的情況下
Regular Expression就挫挫有餘了,我能想到的優點大概這些
1.考績不會變差(當然是針對我個人)
2.成就感,許多本科系畢業的在Compiler都是混過去的吧,會Parser的人還
真不多*(單指台灣)。
3.看Programming Language Spec的時候通常都是用Grammar的語法說明,
不信?去MSDN C#的Spec看每個章節(除第一章外)一開始的定義都是Grammar
的寫法,會了Grammar就看的懂spec看的懂spec就更不容易寫錯程式,
還有有爭執的時候還可以拿spec來壓下屬.....(這點到真的滿好用的,
好吧我承認我有點GY)。
4.可以創造自己的程式語言,想和python作者一樣一舉成名?先學好Parser
絕對是必要的。
5.打發無聊時間.....
--
我的Blog :)
http://spaces.msn.com/members/austinjan/
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 211.75.23.122
推
140.113.164.7 06/01, , 1F
140.113.164.7 06/01, 1F
→
61.229.12.139 06/02, , 2F
61.229.12.139 06/02, 2F
→
61.229.12.139 06/02, , 3F
61.229.12.139 06/02, 3F
→
61.229.12.139 06/02, , 4F
61.229.12.139 06/02, 4F
C_Sharp 近期熱門文章
PTT數位生活區 即時熱門文章