設計模式--解釋器模式C++實現


1定義

給定一門語言,定義他的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子

2類圖

角色分析

AbstractExpression抽象解釋器,具體的解釋任務由各個實現類完成,具體的解釋器分別由TerminalExpression和NonterminalExpression完成

TerminalExpression終結符表達式,實現與文法中的元素相關的解釋操作,通常一個解釋器模式中只能有一個終結符表達式,但有多個實例,敵營不同的終結符

NonterminalExpression非終結符,文法中的每條規則對應一個非終結表達式。

Context環境角色,

3實現

#pragma once
#include<stack>
#include<iostream>
using namespace std;
class Object;
class Context;
//抽象表達式

//抽象表達式是生成語法集合/語法樹的關鍵,每個語法集合完成指定語法解析任務,通過遞歸調用方式完成
class Expression
{
public:
    virtual Object* interpreter(Context *ctx) = 0
    {
        cout << "If you Can, you Don't" << endl;
        return NULL;
    };
};
//終結符表達式簡單,主要處理場景元素和數據的轉換
//終結符表達式
class TerminalExpression :public Expression
{
    Object* interpreter(Context*ctx)
    {
        cout << "TerminalExpression::interpreter" << endl;
        return NULL;
    }
};

//每個非終結符表達式都表示一個文法規則,每個文法規則又只關心周邊文法規則的結果,所以就會有遞歸調用而存在
//非終結符表達式
class NonterminalExpression :public Expression
{
public:
    NonterminalExpression(Expression* x1, ...)
    {
        for (int i = 0; i < 4; ++i)
        {
            _st.push(x1);
        }
    }
    Object *interpreter(Context*ctx)
    {
        //核心支出在於這里。。進行文法處理,並且產生遞歸調用
        //if(typeid().name() != "TerminalExpression")
        //遞歸調用
        //文法處理
        while (!_st.empty())
        {
            Expression* tp = _st.top();
            _st.pop();
            cout << "NoterminalExpression::interpreter" << endl;
            tp->interpreter(ctx);
        }
        return NULL;
    }
private:
    stack <Expression*> _st;
};
class Context{
};

class Client
{
public:
    void operator()()
    {
        Context *ctx = new Context();
        stack<Expression*> st;
        for (int i = 0; i < 5; ++i)
        {
            //進行語法判斷,並且產生遞歸調用
            st.push(new TerminalExpression());
            st.push(new NonterminalExpression(new TerminalExpression()));
        }
        //for (int i = 0; i < 5; ++i)
        //{
        //    //進行語法判斷,並且產生遞歸調用
        //    st.push(new NonterminalExpression(new TerminalExpression()));
        //    st.push(new TerminalExpression());
        //}
        //產生一個完整的語法樹,由各個具體的語法分析進行解析
        Expression *exp = st.top();
        exp->interpreter(ctx);
    }
};

4應用

①優點:是一個簡單的語法分析工具,擴展性良好,修改語法只需要修改相對應的非終結符表達式就可以了,擴展語法只需要增加非終結符類即可

②缺點

解釋器模式引起類膨脹

采用遞歸調用方式

效率問題,循環和引用太多

③使用場景

重復發生的事情可以用解釋器模式(日志分析等)

一個簡單語法需要解釋的場景


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM