一、介绍
解释器模式在实际的系统开发中使用的非常少,因为它会引起效率、性能以及维护等问题,一般在大中型的框架型项目能够找到它的身影,比如一些数据分析工具、报表设计工具、科学计算工具等等,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具
二、举例
整个过程可以用树状结构进行表示,比如,a+b = temp,之后向上传递,其二者的和temp和c做减法,一次类推
三、代码
class Expression {
public:
virtual int interpreter(unordered_map<char, int> var) = 0;
};
// 变量表达式,终止表达式,是一个叶子结点
class VarExpression : public Expression {
char key;
public:
VarExpression(const char &key) {
this->key = key;
}
int interpreter(unordered_map<char, int> var) override {
return var[key];
}
};
// 符号表达式,非终止表达式,非叶子节点
class SymbolExpression : public Expression {
// 运算符
protected:
Expression *left;
Expression *right;
public:
SymbolExpression(Expression *left, Expression *right) :
left(left), right(right) {}
};
// 加法运算
class AddExpression : public SymbolExpression {
public:
AddExpression(Expression *left, Expression *right) :
SymbolExpression(left, right) {}
int interpreter(unordered_map<char, int> var) override {
return left->interpreter(var) + right->interpreter(var);
}
};
// 减法运算
class SubExpression : public SymbolExpression {
public:
SubExpression(Expression *left, Expression *right) :
SymbolExpression(left, right) {}
int interpreter(unordered_map<char, int> var) override {
return left->interpreter(var) - right->interpreter(var);
}
};
// 构建树
Expression *analyse(string expStr) {
stack<Expression *> expStack;
Expression *left = nullptr;
Expression *right = nullptr;
for (int i = 0; i < expStr.size(); i++) {
switch (expStr[i]) {
case '+':
// 加法运算
left = expStack.top();
right = new VarExpression(expStr[++i]);
expStack.push(new AddExpression(left, right));
break;
case '-':
// 减法运算
left = expStack.top();
right = new VarExpression(expStr[++i]);
expStack.push(new SubExpression(left, right));
break;
default:
// 终结表达式
expStack.push(new VarExpression(expStr[i]));
}
}
Expression *expression = expStack.top();
return expression;
}
void release(Expression *expression) {
// 释放表达式树的节点内存...
}
int main() {
//正如这个表达式所述,可以千变万化,但是其中的运算法则是不会发生变化的
string expStr = "a+b-c+d";
unordered_map<char, int> var;
//根据情况,将表达式中的变量赋值为实际的数值
var.insert({'a', 5});
var.insert({'b', 2});
var.insert({'c', 1});
var.insert({'d', 6});
//针对表达式进行解析,获得根结点
Expression *expression = analyse(expStr);
// interpreter函数不断的递归,对表达式进行具体的运算
int result = expression->interpreter(var);
cout << result << endl;
release(expression);
return 0;
}