关于解释器模式看到了一篇讲解的十分好的博客行为型模式—解释器模式 ,自己写了一遍实现,首先要看懂UML类图,理解终结符解释器和非终结符解释器的作用,然后要掌握抽象语法树的构建,理解了这几点之后就很容易利用解释器模式构造自己的解释器
#include <iostream>
#include <string>
#include <map>
#include <stack>
using namespace std;
//抽象解释器(是终结符解释器和非终结符解释器的父类)
class Expression{
public:
virtual int Interpret(map<string,int>& context) = 0;
virtual ~Expression(){}
};
//终结符解释器(在本例中为运算元素解释器)
class VarExpression:public Expression{
public:
VarExpression(string key):m_key(key){}
int Interpret(map<string, int> &context)
{
if(context.end() == context.find(m_key))
{
cout << "未定义运算元素" << m_key <<endl;
return -1;
}
else
return context[m_key];
}
~VarExpression()
{
cout << "~VarExpression()" << endl;
}
private:
string m_key;
};
//非终结符解释器(在本例中为运算符解释器)
class SymbolExpression:public Expression{
public:
SymbolExpression(Expression *leftExp,Expression *rightExp):m_pLeftExp(leftExp),m_pRightExp(rightExp){}
Expression* GetLeftExp()
{
return m_pLeftExp;
}
Expression* GetRightExp()
{
return m_pRightExp;
}
protected:
Expression *m_pLeftExp;
Expression *m_pRightExp;
};
//加法符号解释器
class AddExpression:public SymbolExpression{
public:
AddExpression(Expression *leftExp,Expression *rightExp):SymbolExpression(leftExp,rightExp){}
int Interpret(map<string, int> &context)
{
return m_pLeftExp->Interpret(context) + m_pRightExp->Interpret(context);
}
~AddExpression()
{
cout << "~AddExpression()" << endl;
}
};
/**************如果要添加语义则继承SymbolExpression并重写interpret函数即可**********************/
//Calculator构建抽象语法树,利用二叉树的栈结构来递归实现
class Calculator
{
public:
Calculator(string strExp):m_pResultExp(NULL)
{
//用于存放临时结果的栈
stack<Expression*> resultStack;
Expression *leftExp;
Expression *rightExp;
/*从左到向分析表达式(如:a+b-c),最终的语法树如下:
* -
* / \
* + c
* / \
* a b
*/
for(size_t i=0;i<strExp.size();i++)
{
switch (strExp[i])
{
case '+':
//取出栈顶元素作为左操作数
leftExp = resultStack.top();
resultStack.pop();
//取出下一元素作为右操作数
rightExp = new VarExpression(strExp.substr(++i,1));
//将结果所得存入栈中,此处为AddExp对象
resultStack.push(new AddExpression(leftExp,rightExp));
break;
default:
//如果为终结符解释器,则直接推入栈中
resultStack.push(new VarExpression(strExp.substr(i,1)));
break;
}
}
if(!resultStack.empty())
{
m_pResultExp = resultStack.top();
resultStack.pop();
}
}
//删除抽象语法树
void DeleteTree(Expression *delExp)
{
SymbolExpression *node = dynamic_cast<SymbolExpression*>(delExp);
if(node == NULL)
{
delete delExp;
}
else
{
DeleteTree(node->GetLeftExp());
DeleteTree(node->GetRightExp());
delete delExp;
}
}
int GetResult(map<string,int>& context)
{
return (m_pResultExp == NULL) ? 0 : m_pResultExp->Interpret(context);
}
~Calculator()
{
DeleteTree(m_pResultExp);
m_pResultExp = NULL;
}
private:
Expression *m_pResultExp;
};
int main(int argc,char** argv)
{
string strExp = "a+b+c";
map<string,int> context;
context["a"] = 100;
context["b"] = 50;
context["c"] = 80;
Calculator cal(strExp);
cout << strExp << "的解释结果为: " << cal.GetResult(context) <<endl;
return 0;
}