设计模式--解释器模式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应用

①优点:是一个简单的语法分析工具,扩展性良好,修改语法只需要修改相对应的非终结符表达式就可以了,扩展语法只需要增加非终结符类即可

②缺点

解释器模式引起类膨胀

采用递归调用方式

效率问题,循环和引用太多

③使用场景

重复发生的事情可以用解释器模式(日志分析等)

一个简单语法需要解释的场景

posted @ 2016-04-09 01:32  狼行博客园  阅读(2744)  评论(0编辑  收藏  举报