設計模式筆記—23_Interpreter解析器模式

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模式會產生比較大的類層次結構,需要求助於語法分析器這樣的標準工具
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章