一,简介
解释器模式(interpreter pattern)提供了评估语言的语法或表达式的方式,它属于行为模式。这种模式实现了一个表达式接口,该接口解释了一个特定的上下文。这种模式被用在SQL解析、符号处理引擎等场合。
二,角色
AbstractExpression
抽象表达式,声明一个抽象的解释操作,这个接口为抽象语法树中所有节点共享
TerminalExpression
终结符表达式,实现与文法中的终结符相关联的解释操作
NoterminalExpression
非终结符表达式,为文法中的非终结符实现解释操作。对文法中每一条规则如R1、R2....Rn都需要一个具体的非终结符表达式
三,举例
1,类图
2,代码
class Context {
private:
map<string, int> valueMap;
public:
void addValue(string key, int value) {
valueMap.insert(std::pair<string, int>(key, value));
}
int getValue(string key) {
return valueMap[key];
}
};
class AbstractExpression {
public:
virtual int interpreter(Context context) = 0;
};
class AddNoterminalExpression :public AbstractExpression {
private:
AbstractExpression* left;
AbstractExpression* right;
public:
AddNoterminalExpression(AbstractExpression* left, AbstractExpression*right) {
this->left = left;
this->right = right;
}
int interpreter(Context context) {
return this->left->interpreter(context) +
this->right->interpreter(context);
}
};
class SubtractNoterminalExpression: public AbstractExpression
{
private:
AbstractExpression* left;
AbstractExpression* right;
public:
SubtractNoterminalExpression(AbstractExpression *left,AbstractExpression *right)
{
this->left = left;
this->right= right;
}
int interpreter(Context context)
{
return this->left->interpreter(context) - this->right->interpreter(context);
}
};
class TerminalExpression :public AbstractExpression {
private:
int i;
public:
TerminalExpression(int i) {
this->i = i;
}
int interpreter(Context context) {
return this->i;
}
};
int main()
{
//计算 a-b+c
Context context;
context.addValue("a", 7);
context.addValue("b", 5);
context.addValue("c", 2);
SubtractNoterminalExpression *subtractValue = new SubtractNoterminalExpression(new TerminalExpression(context.getValue("a")), new TerminalExpression(context.getValue("b")));
AddNoterminalExpression *addValue = new AddNoterminalExpression(subtractValue, new TerminalExpression(context.getValue("c")));
cout << addValue->interpreter(context);
system("pause");
return 0;
}
四,优缺点
优点: 1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。
缺点: 1、可利用场景比较少。 2、对于复杂的文法比较难维护。 3、解释器模式会引起类膨胀。 4、解释器模式采用递归调用方法。
五,使用场景
1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
2、一些重复出现的问题可以用一种简单的语言来进行表达。
3、一个简单语法需要解释的场景。