解释器模式(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;
}