Interpreter解析器模式是一種“領域規則”模式
- 在特定領域中,某些變化雖然頻繁,但可以抽象爲某種規則。這時候,結合特定領域,將問題抽象爲語法規則,從而給出在該領域下的一般性解決方案
動機
- 在軟件構建過程中,如果某一特定領域的問題比較複雜,類似的結構在不斷重複出現,如果使用普通的編程方式來實現將面臨非常頻繁的變化
- 在這種情況下,將特定領域的問題表達爲某種語法規則下的句子,然後構建一個解釋器來解釋這樣的句子,從而達到解決問題的目的
定義
- 給定一個語言,定義它的文法的一種表示,並定義一種解釋器,這個解釋器使用該表示來解釋語言中的句子
結構
代碼對比
main.cpp
#include <iostream>
#include <map>
#include <stack>
using namespace std;
class Expression {
public:
virtual int interpreter(map<char, int> var)=0;
virtual ~Expression(){}
};
//變量表達式
class VarExpression: public Expression {
char key;
public:
VarExpression(const char& key)
{
this->key = key;
}
int interpreter(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(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(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(int argc, const char * argv[]) {
string expStr = "a+b-c+d-e";
map<char, int> var;
var.insert(make_pair('a',5));
var.insert(make_pair('b',2));
var.insert(make_pair('c',1));
var.insert(make_pair('d',6));
var.insert(make_pair('e',10));
Expression* expression= analyse(expStr);
int result=expression->interpreter(var);
cout<<result<<endl;
release(expression);
return 0;
}
說明
要點總結
- Interpreter模式的應用場合是Interpreter模式應用中的難點。只有滿足“業務規則頻繁變化,且類似的結構不斷重複出現,並且容易抽象爲語法規則的問題”才適合使用Interpreter模式
- 使用Interpreter模式來表示文法規則,從而可以使用面向對象技巧來方便地“擴展”文法
- Interpreter模式比較適合簡單地文法表示。對於複雜的文法表示,Interpreter模式會產生比較大的類層次結構,需要求助於語法分析器這樣的標準工具