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

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

    ②缺点

    解释器模式引起类膨胀

    采用递归调用方式

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

    ③使用场景

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

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

  • 相关阅读:
    java实现RSA非对称加密
    lombok中的@Builder注解
    java实现大文件的分割与合并
    IDEA新建springboot选择DevTools
    bat命令自动配置java环境变量
    java实现发送邮件
    随记
    编译原理学习——FIRST和LASTVT
    国王的游戏
    JAVA类加载及NEW对象的过程
  • 原文地址:https://www.cnblogs.com/lang5230/p/5370497.html
Copyright © 2020-2023  润新知