1定義 給定一門語言,定義他的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子 2類圖 角色分析 AbstractExpression抽象解釋器,具體的解釋任務由各個實現類完成,具體的解釋器分別由TerminalExpression和NonterminalExpression完 ...
1定義
給定一門語言,定義他的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子
2類圖
角色分析
AbstractExpression抽象解釋器,具體的解釋任務由各個實現類完成,具體的解釋器分別由TerminalExpression和NonterminalExpression完成
TerminalExpression終結符表達式,實現與文法中的元素相關的解釋操作,通常一個解釋器模式中只能有一個終結符表達式,但有多個實例,敵營不同的終結符
NonterminalExpression非終結符,文法中的每條規則對應一個非終結表達式。
Context環境角色,
3實現
#pragma once #include<stack> #include<iostream> using namespace std; class Object; class Context; //抽象表達式 //抽象表達式是生成語法集合/語法樹的關鍵,每個語法集合完成指定語法解析任務,通過遞歸調用方式完成 class Expression { public: virtual Object* interpreter(Context *ctx) = 0 { cout << "If you Can, you Don't" << endl; return NULL; }; }; //終結符表達式簡單,主要處理場景元素和數據的轉換 //終結符表達式 class TerminalExpression :public Expression { Object* interpreter(Context*ctx) { cout << "TerminalExpression::interpreter" << endl; return NULL; } }; //每個非終結符表達式都表示一個文法規則,每個文法規則又只關心周邊文法規則的結果,所以就會有遞歸調用而存在 //非終結符表達式 class NonterminalExpression :public Expression { public: NonterminalExpression(Expression* x1, ...) { for (int i = 0; i < 4; ++i) { _st.push(x1); } } Object *interpreter(Context*ctx) { //核心支出在於這裡。。進行文法處理,並且產生遞歸調用 //if(typeid().name() != "TerminalExpression") //遞歸調用 //文法處理 while (!_st.empty()) { Expression* tp = _st.top(); _st.pop(); cout << "NoterminalExpression::interpreter" << endl; tp->interpreter(ctx); } return NULL; } private: stack <Expression*> _st; }; class Context{ }; class Client { public: void operator()() { Context *ctx = new Context(); stack<Expression*> st; for (int i = 0; i < 5; ++i) { //進行語法判斷,並且產生遞歸調用 st.push(new TerminalExpression()); st.push(new NonterminalExpression(new TerminalExpression())); } //for (int i = 0; i < 5; ++i) //{ // //進行語法判斷,並且產生遞歸調用 // st.push(new NonterminalExpression(new TerminalExpression())); // st.push(new TerminalExpression()); //} //產生一個完整的語法樹,由各個具體的語法分析進行解析 Expression *exp = st.top(); exp->interpreter(ctx); } };
4應用
①優點:是一個簡單的語法分析工具,擴展性良好,修改語法只需要修改相對應的非終結符表達式就可以了,擴展語法只需要增加非終結符類即可
②缺點
解釋器模式引起類膨脹
採用遞歸調用方式
效率問題,迴圈和引用太多
③使用場景
重覆發生的事情可以用解釋器模式(日誌分析等)
一個簡單語法需要解釋的場景