解释器模式(Interpreter Pattern):给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 (用在SQL解析、符号处理引擎等)
解释器模式:
对输入的内容,构建语法树,按照特定的规则进行解析。
概要分析:
就是对输入的字符进行语法,词法分析,比如数学运算的计算等
使用场景:
比如:处理器,硬盘控制器,浏览器等对输入的信息做不同的解析。
比如:使用指令,控制一套机器人系统
样例Demo:
参考来源:设计模式C++实现(20)——解释器模式_crkres9527-CSDN博客_c++ 解释器模式
感觉这个时解释器的精髓:把复杂的输入解析出想要的结果。 直接拿来用,没有细节分析
//行为型模式:解释器模式 //场景:四则运算 #include <iostream> #include <string> #include <map> #include <stack> #include <typeinfo> using namespace std; //*******************************************抽象表达式类*********************************** class Expression { public: //解析公式和数值,其中var中的key是公式中的参数,value值是具体的数字 //如a = 100; b = 20; c = 40 virtual int interpreter(map<string, int>& var) = 0; virtual ~Expression(){}; }; //变量解析器(终结符表达式) class VarExpression : public Expression { string key; public: VarExpression(string key) { this->key = key; } //从map中取出变量的值 int interpreter(map<string, int>& var) { return var[key]; } ~VarExpression() { cout << "~VarExpression()" << endl; } }; //**********抽象运算符号解析器*********************** //抽象运算符号解析器 class SymbolExpression : public Expression { protected: Expression* left; Expression* right; public: SymbolExpression(Expression* left, Expression* right) { this -> left = left; this -> right = right; } Expression* getLeft() { return left; } Expression* getRight() { return right; } }; //加法解析器 class AddExpression : public SymbolExpression { public: AddExpression(Expression* left, Expression* right): SymbolExpression(left,right) { } //把左右两个表达式运算的结果加起来 int interpreter(map<string, int>& var) { return left->interpreter(var) + right ->interpreter(var); } ~AddExpression() { cout << "~AddExpression()" << endl; } }; //减法解析器 class SubExpression : public SymbolExpression { public: SubExpression(Expression* left, Expression* right): SymbolExpression(left,right) { } //把左右两个表达式运算的结果相减 int interpreter(map<string, int>& var) { return left->interpreter(var) - right ->interpreter(var); } ~SubExpression() { cout << "~SubExpression()" << endl; } }; //*********************************解析器封装类*************************************** //解析器封装类,这个类是根据迪米特法则进行封装,目的是让Client只与直接朋友打交道,相当于Facade class Calculator { private: Expression* expression; public: //构造函数传参,并解析表达式,构建语法树 Calculator(string expStr) { expression = NULL; //栈,用来暂存中间结果 stack<Expression*> stkExp; Expression* left = NULL; Expression* right = NULL; /*从左到向分析表达式(如:a+b-c),最终的语法树如下: * - * / \ * + c * / \ * a b */ for(unsigned int i = 0; i< expStr.length(); i++) { switch(expStr[i]) { case '+': //加法 //1.先从栈中取出左操作数 left = stkExp.top(); stkExp.pop(); //2.从表达式中取出+号后面的右操作数,并生成终结符解析对象 right = new VarExpression(expStr.substr(++i,1)); //3.将左右操作数相加,并把结果放入栈中 stkExp.push(new AddExpression(left, right)); break; case '-': //1.先从栈中取出左操作数 left = stkExp.top(); stkExp.pop(); //2.从表达式中取出+号后面的右操作数,并生成终结符解析对象 right = new VarExpression(expStr.substr(++i,1)); //3.将左右操作数相减,并把结果放入栈中 stkExp.push(new SubExpression(left, right)); break; default: //如果是变量(终结符):如a+b+c中的a\b\c, //则直接生成对应的变量解析器对象 stkExp.push(new VarExpression(expStr.substr(i,1))); } } //栈中保存的就是最终语法树的根结点(本例为SuuExpression对象) if(!stkExp.empty()) { expression = stkExp.top(); stkExp.pop(); } } void deltree(Expression* expression) { SymbolExpression* branch = dynamic_cast<SymbolExpression*>(expression); //叶子结点 if (branch == NULL) { delete expression; } else //分支结点 { //左子树 deltree(branch->getLeft()); //右子树 deltree(branch->getRight()); //结点 delete expression; } } ~Calculator() { deltree(expression); expression = NULL; } //开始运算 int run(map<string, int>& var) { return (expression == NULL) ? 0 : expression->interpreter(var); } }; int main() { string expStr = "a+b-c"; //为简化处理,这里必须是合法的表达式 map<string, int> var; //相当于Interpreter模式中的Context var["a"] = 100; var["b"] = 20; var["c"] = 40; Calculator cal(expStr); cout <<"运算结果为:" << expStr << " = " << cal.run(var) << endl; return 0; } /* 运算结果为:a+b-c = 80 ~VarExpression() ~VarExpression() ~AddExpression() ~VarExpression() ~SubExpression() */
demo2:也是参考,只是简单梳理:
//解释器模式 #include <iostream> #include <string> using namespace std; //只是提供一个解释器的中间类,为解释语句做辅助功能,输入要时特定的格式 class Context { public: //通过此类进行中间变量的存储和运算,得到数据通过此类,修改也是通过此类 Context(int num){ m_num = num;} public: void setNum(int num){ m_num = num;} int getNum(){ return m_num;} void setRes(int res){ m_res = res;} int getRes(){ return m_res;} private: int m_num; int m_res; }; //解释器基类 调用接口的入口而已,子类真正调用入参,根据不同的解释做处理 //可以定义一个基类 实现多个子类不同的解释功能,如运算符+,-,*,/ class Expression { public: virtual void interpreter(Context *context) = 0; }; //可以对输入做不同的解析 这里只做了输出 class PlusExpression : public Expression { public: virtual void interpreter(Context *context) { int num = context->getNum(); num++; context->setNum(num); context->setRes(num); } }; //可以对输入做不同的解析 这里只做了输出 class MinusExpression : public Expression { public: virtual void interpreter(Context *context) { int num = context->getNum(); num--; context->setNum(num); context->setRes(num); } }; int main() { //通过一个中间类进行数据的存储转化和设置 Context *explain = new Context(10);//设置要解释的内容 Expression *e1 = new PlusExpression;//设置解释器 e1->interpreter(explain);//调用解释器内的解释函数 cout << "PlusExpression:" << explain->getRes() << endl;//得到数据结果 Expression *e2 = new MinusExpression; e2->interpreter(explain); cout << "MinusExpression:" << explain->getRes() << endl; delete explain; delete e2; delete e1; // system("pause"); return 0; }