解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
优点:容易改变和扩展文法,因为该模式使用类来表示文法规则,可以使用继承来改变或扩展该文法,比较容易实现文法,因为定义抽象语法树中各个节点的类实现大体类似,易于直接编写。
不足:解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。文法容易时,可使用。
解释器模式并不像前面的设计模式易懂。下面给出代码理解。
解释器模式范例:
#include<iostream>
#include <string>
#include <list>
using namespace std;
class Context;
class AbstractExpression
{
public:
virtual void Interpret(Context* context) = 0;
};
class TerminalExpression: public AbstractExpression
{
public:
void Interpret(Context* context)
{
cout << "终端解释器" << endl;
}
};
class NonterminalExprssion : public AbstractExpression
{
void Interpret(Context* context)
{
cout << "非终端解释器" << endl;
}
};
class Context
{
public:
string getInput()
{
return input;
}
void setInput(string value)
{
input = value;
}
string getOutput()
{
return output;
}
void setOutput(string value)
{
output = value;
}
private:
string input;
string output;
};
int main()
{
Context* context = new Context();
list<AbstractExpression*> List;
List.push_back(new TerminalExpression());
List.push_back(new NonterminalExprssion());
List.push_back(new TerminalExpression());
List.push_back(new TerminalExpression());
for(int i = 0;i < 4;i++)
{
AbstractExpression* exp = List.back();
exp->Interpret(context);
List.pop_back();
}
return 0;
}
解释器模式中会用到一些负责的算法,容器等一些知识。文法的实现比较难于理解,但过于复杂又不适合,如果文法非常复杂时,建议使用其他的技术,如语法分析程序或编译器生成器来处理。
解释器模式实例:
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <typeinfo>
using namespace std;
class Expression
{
public:
virtual int interpreter(map<string,int>& var) = 0;
virtual ~Expression(){}
};
class VarExpression : public Expression
{
public:
VarExpression(string key)
{
this->key = key;
}
int interpreter(map<string,int>& var)
{
return var[key];
}
~VarExpression()
{
//cout << "~VarExpression()" << endl;
}
private:
string key;
};
class SymbolExpression : public Expression
{
public:
SymbolExpression(Expression* left,Expression* right)
{
this->left = left;
this->right = right;
}
Expression* getLeft()
{
return left;
}
Expression* getRight()
{
return right;
}
protected:
Expression* left;
Expression* 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;
}
};
class Calculator
{
public:
Calculator(string expStr)
{
expression = NULL;
stack<Expression*> st;
Expression* left = NULL;
Expression* right = NULL;
for(unsigned int i = 0;i < expStr.length();i++)
{
switch(expStr[i])
{
case '+':
left = st.top();
st.pop();
right = new VarExpression(expStr.substr(++i,1));
st.push(new AddExpression(left,right));
break;
case '-':
left = st.top();
st.pop();
right = new VarExpression(expStr.substr(++i,1));
st.push(new SubExpression(left,right));
break;
default:
st.push(new VarExpression(expStr.substr(i,1)));
}
}
if(!st.empty())
{
expression = st.top();
st.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);
}
private:
Expression* expression;
};
int main()
{
string expStr = "a+b-c";
map<string,int> var;
var["a"] = 100;
var["b"] = 20;
var["c"] = 30;
Calculator cal(expStr);
cout << "运算结果为:" << expStr << "=" << cal.run(var) << endl;
return 0;
}