[心得] Parser

看板C_Sharp (C#)作者 (Op穎)時間20年前 (2005/06/01 19:01), 編輯推噓1(103)
留言4則, 2人參與, 最新討論串1/1
所謂的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
C/C++ 程式碼 ->處理 ->所有function,symbol列表
61.229.12.139 06/02, 2F

61.229.12.139 06/02, , 3F
根據列表產生Document,和一些檢查的動作
61.229.12.139 06/02, 3F

61.229.12.139 06/02, , 4F
比如命名有無符合規範等等.
61.229.12.139 06/02, 4F
文章代碼(AID): #12dPLiAA (C_Sharp)
文章代碼(AID): #12dPLiAA (C_Sharp)