设计模式C++实现--Interpreter模式
2019獨角獸企業重金招聘Python工程師標準>>>
解釋器模式
解釋器模式(Interpreter Pattern)提供了評估語言的語法或表達式的方式,它屬于行為型模式。這種模式實現了一個表達式接口,該接口解釋一個特定的上下文。這種模式被用在 SQL 解析、符號處理引擎等。
適用性:
在以下情況下可以考慮使用解釋器模式:
(1)?可以將一個需要解釋執行的語言中的句子表示為一個抽象語法樹。
(2)??一些重復出現的問題可以用一種簡單的語言來進行表達。
(3)?一個語言的文法較為簡單。
(4)?執行效率不是關鍵問題。(注:高效的解釋器通常不是通過直接解釋抽象語法樹來實現的,而是需要將它們轉換成其他形式,使用解釋器模式的執行效率并不高。)
優缺點:
優點:
(1)?易于改變和擴展文法。由于在解釋器模式中使用類來表示語言的文法規則,因此可以通過繼承等機制來改變或擴展文法。
(2)?每一條文法規則都可以表示為一個類,因此可以方便地實現一個簡單的語言。
(3)?實現文法較為容易。在抽象語法樹中每一個表達式節點類的實現方式都是相似的,這些類的代碼編寫都不會特別復雜,還可以通過一些工具自動生成節點類代碼。
(4)?增加新的解釋表達式較為方便。如果用戶需要增加新的解釋表達式只需要對應增加一個新的終結符表達式或非終結符表達式類,原有表達式類代碼無須修改,符合“開閉原則”。
缺點:
(1)?對于復雜文法難以維護。在解釋器模式中,每一條規則至少需要定義一個類,因此如果一個語言包含太多文法規則,類的個數將會急劇增加,導致系統難以管理和維護,此時可以考慮使用語法分析程序等方式來取代解釋器模式。
(2)?執行效率較低。由于在解釋器模式中使用了大量的循環和遞歸調用,因此在解釋較為復雜的句子時其速度很慢,而且代碼的調試過程也比較麻煩。
總論:
盡量不要在重要模塊中使用解釋器模式,因為維護困難。在項目中,可以使用腳本語言來代替解釋器模式。
實現
? ? ? ? ? ? ??
抽象表達式角色(AbstractExpression):?聲明一個抽象的解釋操作,這個接口為所有具體表達式角色都要實現的。
終結符表達式角色(TerminalExpression):?實現與文法中的元素相關聯的解釋操作,通常一個解釋器模式中只有一個終結符表達式,但有多個實例對應不同的終結符,
終結符就是語言中用到的基本元素,一般不能再被分解,如:?x?->?xa,?這里a是終結符,因為沒有別的規則可以把a變成別的符號,不過x可以變成別的符號,所以x是非終結符。
非終結符表達式角色(NonterminalExpression):?文法中的每條規則對應于一個非終結表達式,?非終結表達式根據邏輯的復雜程度而增加,原則上每個文法規則都對應一個非終結符表達式。
環境角色(Context):包含解釋器之外的一些全局信息。
步驟 1
創建上下文
class Contex{ private:map<string,int> _valueMap;public:int getValue(const string & key){return _valueMap[key];}void addValue( const string & key,int value){_valueMap.insert(pair<string,int>(key,value));} };?
步驟 2
創建抽象表達式接口
class AbstractExpression{ public:virtual ~ AbstractExpression(){}virtual int interpreter(Contex & contex) = 0; };?
步驟 3
創建兩種非終結表達式
class AddNonterminalExpression : public AbstractExpression{ private:AbstractExpression * _left;AbstractExpression * _right; public:AddNonterminalExpression(AbstractExpression * left,AbstractExpression * right):_left(left),_right(right){}int interpreter(Contex &contex) override {return _left->interpreter(contex) + _right->interpreter(contex);} };class SubNonterminalExpression : public AbstractExpression{ private:AbstractExpression * _left;AbstractExpression * _right; public:SubNonterminalExpression(AbstractExpression *_left, AbstractExpression *_right) : _left(_left), _right(_right) {}int interpreter(Contex &contex) override {return _left->interpreter(contex) - _right->interpreter(contex);} };?
步驟 4
創建終結表達式實現
class TerminalExpresiion : public AbstractExpression{ private:int _i;//終結符不能再切割 public:TerminalExpresiion(int i) : _i(i) {}int interpreter(Contex &contex) override {return _i;} };?
步驟 5
驗證
Contex contex;contex.addValue("a",1);contex.addValue("b",2);contex.addValue("c",3);AbstractExpression * sub_left = new TerminalExpresiion(contex.getValue("a"));AbstractExpression * sub_right = new TerminalExpresiion(contex.getValue("b"));AbstractExpression * subvalue = new SubNonterminalExpression(sub_left,sub_right);AbstractExpression * add_right = new TerminalExpresiion(contex.getValue("c"));AbstractExpression * addvalue = new AddNonterminalExpression(subvalue,add_right);std::cout << addvalue->interpreter(contex) << std::endl;delete(addvalue);delete(add_right);delete(subvalue);delete(sub_right);delete(sub_left);輸出結果
2?
轉載于:https://my.oschina.net/fileoptions/blog/1823480
總結
以上是生活随笔為你收集整理的设计模式C++实现--Interpreter模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android中ScrollView嵌套
- 下一篇: C++之引用的详解