动机:在软件构建过程中,如果某一个特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。
定义:给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。
代码表示:
#include<iostream>
#include<map>
#include<stack>
#include<typeinfo>
class Expression {
public:
virtual int interpreter(std::map<char, int>& var)=0;
virtual ~Expression(){}
};
class VarExpression: public Expression {
public:
VarExpression(const char& key): m_key(key){
}
int interpreter(std::map<char, int>& var)override {
return var[m_key];
}
private:
char m_key;
};
class SymbolExpression: public Expression {
public:
SymbolExpression(Expression* lleft, Expression* lright): right(lright), left(lleft){
}
//protected:
Expression* left;
Expression* right;
};
class PlusExpression: public SymbolExpression{
public:
PlusExpression(Expression* left, Expression* right): SymbolExpression(left, right){
}
int interpreter(std::map<char, int>& var) {
return left->interpreter(var) + right->interpreter(var);
}
};
class MinExpression: public SymbolExpression{
public:
MinExpression(Expression* left, Expression* right): SymbolExpression(left, right){
}
int interpreter(std::map<char, int>& var) {
return left->interpreter(var) - right->interpreter(var);
}
};
Expression* analyze(std::string expStr) {
std::stack<Expression*> expStack;
Expression* left;
Expression* right;
for (int i=0; i< expStr.size(); i++){
switch(expStr[i]){
case '+':
{
left = expStack.top();
right = new VarExpression(expStr[++i]);
expStack.push(new PlusExpression(left, right));
break;
}
case '-':
{
left = expStack.top();
right = new VarExpression(expStr[++i]);
expStack.push(new MinExpression(left, right));
break;
}
default:
{
expStack.push(new VarExpression(expStr[i]));
}
}
}
return expStack.top();
}
void release(Expression* exp){
std::string name = typeid(*exp).name();
std::cout << name << std::endl;
SymbolExpression* sExp = dynamic_cast<SymbolExpression*>(exp);
if (sExp != nullptr){
release(sExp->left);
release(sExp->right);
} else {
delete exp;
}
}
int main(int argc, char** argv){
const char* expStr = "a+b-c-d";
std::map<char, int> var;
var.insert(std::make_pair<char, int>('a', 10));
var.insert(std::make_pair<char, int>('b', 1));
var.insert(std::make_pair<char, int>('c', 2));
var.insert(std::make_pair<char, int>('d', 2));
//var.insert(std::make_pair<char, int>('e', 11));
Expression* exp = analyze(expStr);
int result = exp->interpreter(var);
std::cout << "result:" << result << std::endl;
release(exp);
return 0;
}