可配置文法分析器開發紀事(一) 構造文法樹

來源:互聯網
上載者:User

就像之前的部落格文章所說的,(主要還是)因為GacUI的原因,我決定開發一個更好的可配置輕量級文法分析器來代替之前的落後的版本。在說這個文章之前,我還是想在此向大家推薦一本《程式設計語言實現模式》,這的確是一本好書,讓我相見恨晚。

其實說到開發文法分析器,我從2007年就已經開始在思考類似的問題了。當時C++還處於用的不太熟練的時候,難免會做出一些傻逼的事情,不過總的來說當年的idea還是能用的。從那時候開始,我為了鍛煉自己,一直在實現各種不同的語言。所以給自己開發一個可配置文法分析器也是在所難免的事情了。於是就有:    

第一版:http://hi.baidu.com/geniusvczh/archive/tag/syngram%E6%97%A5%E5%BF%97

第二版:http://www.cppblog.com/vczh/archive/2009/04/06/79122.html

第三版:http://www.cppblog.com/vczh/archive/2009/12/13/103101.html

還有第三版的教程:http://www.cppblog.com/vczh/archive/2010/04/28/113836.html

上面的所有分析器都致力於在C++裡面可以通過直接描述文法和一些語義行為來讓系統可以迅速構造出一個針對特定目的的用起來方便的文法分析器,而“第三版”就是到目前為止還在用的一個版本。至於為什麼我要做一個新的——也就是第四版——之前的文章已經說了。

而今天,第四版的開發已經開始了有好幾天。如果大家關心進度的話,可以去GacUI的Codeplex頁面下載代碼,然後閱讀Common\Source\Parsing下面的源檔案。對應的單元測試可以在Common\UnitTest\UnitTest\TestParsing.cpp裡找到。

於是今天就說說關於構造文法樹的事情。

用C++寫過parser的人都知道,構造文法樹以及語義分析用的符號表是一件極其繁瑣,而且一不小心就容易寫出翔的事情。但是根據我寫過無窮多棵文法樹以及構造過無窮多個符號表以及附帶的副作用,翔,啊不,經驗,做這個事情還是有一些方法的。

在介紹這個方法之前,首先要說一句,人肉做完下面的所有事情是肯定要瘋掉的,所以這一次的可配置文法分析器我已經決定了一定要TMD寫出一個產生文法樹的C++代碼的工具。

一顆文法樹,其實就是一大堆互相繼承的類。一切成熟的文法樹結構所具有的共同特徵,不是他的成員怎麼安排,而是他一定會附帶一個visitor模式的機制。至於什麼是visitor模式,大家請自行參考設計模式,我就不多說廢話了。這一次的可配置文法分析器是帶有一個描述性文法的。也就是說,跟Antlr或者Yacc一樣,首先在一個文字檔裡面準備好文法樹結構和文法規則,然後我的工具會幫你產生一個記憶體中的文法分析器,以及用C++描述的文法樹的聲明和實現檔案。這個描述性文法就類似下面的這個大家熟悉到不能再熟悉的帶函數的四則運算運算式結構:

class Expression{}    class NumberExpression : Expression{    token value;}    class BinaryExpression : Expression{    enum BinaryOperator    {        Add,        Sub,        Mul,        Div,    }        Expression firstOperand;    Expression secondOperand;    BinaryOperator binaryOperator;}    class FunctionExpression : Expression{    token functionName;    Expression[] arguments;}    token NAME = "[a-zA-Z_]/w*";token NUMBER = "/d+(./d+)";token ADD = "/+";token SUB = "-";token MUL = "/*";token DIV = "//";token LEFT = "/(";token RIGHT = "/)";token COMMA = ",";    rule NumberExpression Number        = NUMBER : value;    rule FunctionExpression Call        = NAME : functionName "(" [ Exp : arguments { "," Exp : arguments } ] ")";    rule Expression Factor        = !Number | !Call;    rule Expression Term        = !Factor;        = Term : firstOperand "*" Factory : secondOperand as BinaryExpression with { binaryOperator = "Mul" };        = Term : firstOperand "/" Factory : secondOperand as BinaryExpression with { binaryOperator = "Div" };    rule Expression Exp        = !Term;        = Exp : firstOperand "+" Term : secondOperand as BinaryExpression with { binaryOperator = "Add" };        = Exp : firstOperand "-" Term : secondOperand as BinaryExpression with { binaryOperator = "Sub" };

本欄目更多精彩內容:http://www.bianceng.cn/Programming/cplus/

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。