行为型 解释器模式

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 行为型 解释器模式

解释器模式(Interpreter Pattern):给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 (用在SQL解析、符号处理引擎等)

解释器模式:

对输入的内容,构建语法树,按照特定的规则进行解析。

概要分析:

就是对输入的字符进行语法,词法分析,比如数学运算的计算等

使用场景:

比如:处理器,硬盘控制器,浏览器等对输入的信息做不同的解析。

比如:使用指令,控制一套机器人系统

样例Demo:

参考来源:设计模式C++实现(20)——解释器模式_crkres9527-CSDN博客_c++ 解释器模式

感觉这个时解释器的精髓:把复杂的输入解析出想要的结果。 直接拿来用,没有细节分析

//行为型模式:解释器模式
//场景:四则运算
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <typeinfo>
using namespace std;
//*******************************************抽象表达式类***********************************
class Expression
{
public:
    //解析公式和数值,其中var中的key是公式中的参数,value值是具体的数字
    //如a = 100; b = 20; c = 40
    virtual int interpreter(map<string, int>& var) = 0;
    virtual ~Expression(){};
};
//变量解析器(终结符表达式)
class VarExpression : public Expression
{
    string key;
public:
    VarExpression(string key)
    {
        this->key = key;
    }
    //从map中取出变量的值
    int interpreter(map<string, int>& var)
    {
        return var[key];
    }
    ~VarExpression()
    {
        cout << "~VarExpression()" << endl;
    }
};
//**********抽象运算符号解析器***********************
//抽象运算符号解析器
class SymbolExpression : public Expression
{
protected:
    Expression* left;
    Expression* right;
public:
    SymbolExpression(Expression* left, Expression* right)
    {
        this -> left = left;
        this -> right = right;
    }
    Expression* getLeft()
    {
        return left;
    }
    Expression* getRight()
    {
        return right;
    }
};
//加法解析器
class AddExpression : public SymbolExpression
{
public:
    AddExpression(Expression* left, Expression* right): SymbolExpression(left,right)
    {
    }
    //把左右两个表达式运算的结果加起来
    int interpreter(map<string, int>& var)
    {
        return left->interpreter(var) + right ->interpreter(var);
    }
    ~AddExpression()
    {
        cout << "~AddExpression()" << endl;
    }
};
//减法解析器
class SubExpression : public SymbolExpression
{
public:
    SubExpression(Expression* left, Expression* right): SymbolExpression(left,right)
    {
    }
    //把左右两个表达式运算的结果相减
    int interpreter(map<string, int>& var)
    {
        return left->interpreter(var) - right ->interpreter(var);
    }
    ~SubExpression()
    {
        cout << "~SubExpression()" << endl;
    }
};
//*********************************解析器封装类***************************************
//解析器封装类,这个类是根据迪米特法则进行封装,目的是让Client只与直接朋友打交道,相当于Facade
class Calculator
{
private:
    Expression* expression;
public:
    //构造函数传参,并解析表达式,构建语法树
    Calculator(string expStr)
    {
        expression = NULL;
        //栈,用来暂存中间结果
        stack<Expression*> stkExp;
        Expression* left  = NULL;
        Expression* right = NULL;
        /*从左到向分析表达式(如:a+b-c),最终的语法树如下:
         *           -
         *         /   \
         *       +     c
         *     /   \
         *    a     b
        */
        for(unsigned int i = 0; i< expStr.length(); i++)
        {
            switch(expStr[i])
            {
            case '+':  //加法
                //1.先从栈中取出左操作数
                left = stkExp.top();
                stkExp.pop();
                //2.从表达式中取出+号后面的右操作数,并生成终结符解析对象
                right = new VarExpression(expStr.substr(++i,1));
                //3.将左右操作数相加,并把结果放入栈中
                stkExp.push(new AddExpression(left, right));
                break;
            case '-':
                //1.先从栈中取出左操作数
                left = stkExp.top();
                stkExp.pop();
                //2.从表达式中取出+号后面的右操作数,并生成终结符解析对象
                right = new VarExpression(expStr.substr(++i,1));
                //3.将左右操作数相减,并把结果放入栈中
                stkExp.push(new SubExpression(left, right));
                break;
            default:
                //如果是变量(终结符):如a+b+c中的a\b\c,
                //则直接生成对应的变量解析器对象
                stkExp.push(new VarExpression(expStr.substr(i,1)));
            }
        }
        //栈中保存的就是最终语法树的根结点(本例为SuuExpression对象)
        if(!stkExp.empty())
        {
            expression = stkExp.top();
            stkExp.pop();
        }
    }
    void deltree(Expression* expression)
    {
        SymbolExpression* branch = dynamic_cast<SymbolExpression*>(expression);
        //叶子结点
        if (branch == NULL)
        {
            delete expression;
        }
        else  //分支结点
        {
            //左子树
            deltree(branch->getLeft());
            //右子树
            deltree(branch->getRight());
            //结点
            delete expression;
        }
    }
    ~Calculator()
    {
        deltree(expression);
        expression = NULL;
    }
    //开始运算
    int run(map<string, int>& var)
    {
        return (expression == NULL) ? 0 : expression->interpreter(var);
    }
};
int main()
{
    string expStr = "a+b-c"; //为简化处理,这里必须是合法的表达式
    map<string, int> var;   //相当于Interpreter模式中的Context
    var["a"] = 100;
    var["b"] = 20;
    var["c"] = 40;
    Calculator cal(expStr);
    cout <<"运算结果为:" << expStr << " = " << cal.run(var) << endl;
    return 0;
}
/*
运算结果为:a+b-c = 80
~VarExpression()
~VarExpression()
~AddExpression()
~VarExpression()
~SubExpression()
*/

demo2:也是参考,只是简单梳理:

//解释器模式
#include <iostream>
#include <string>
using namespace std;
//只是提供一个解释器的中间类,为解释语句做辅助功能,输入要时特定的格式
class Context
{
  public: //通过此类进行中间变量的存储和运算,得到数据通过此类,修改也是通过此类
    Context(int num){ m_num = num;}
  public:
    void setNum(int num){ m_num = num;}
    int getNum(){ return m_num;}
    void setRes(int res){ m_res = res;}
    int getRes(){ return m_res;}
  private:
    int m_num;
    int m_res;
};
//解释器基类   调用接口的入口而已,子类真正调用入参,根据不同的解释做处理 
//可以定义一个基类 实现多个子类不同的解释功能,如运算符+,-,*,/
class Expression
{
public:
  virtual void interpreter(Context *context) = 0;
};
//可以对输入做不同的解析  这里只做了输出
class PlusExpression : public Expression
{
public:
  virtual void interpreter(Context *context)
  {
    int num = context->getNum();
    num++;
    context->setNum(num);
    context->setRes(num);
  }
};
//可以对输入做不同的解析  这里只做了输出
class MinusExpression : public Expression
{
public:
  virtual void interpreter(Context *context)
  {
    int num = context->getNum();
    num--;
    context->setNum(num);
    context->setRes(num);
  }
};
int main()
{  
  //通过一个中间类进行数据的存储转化和设置
  Context *explain = new Context(10);//设置要解释的内容
  Expression *e1 = new PlusExpression;//设置解释器
  e1->interpreter(explain);//调用解释器内的解释函数
  cout << "PlusExpression:" << explain->getRes() << endl;//得到数据结果
  Expression *e2 = new MinusExpression;
  e2->interpreter(explain);
  cout << "MinusExpression:" << explain->getRes() << endl;
  delete explain;
  delete e2;
  delete e1;
  // system("pause");
  return 0;
}
目录
相关文章
|
8月前
|
设计模式 移动开发 数据库
行为型设计模式10-解释器模式
行为型设计模式10-解释器模式
64 1
|
1月前
|
设计模式
【设计模式】解释器模式
【设计模式】解释器模式
|
1月前
|
设计模式 监控 Java
聊聊Java设计模式-解释器模式
解释器模式(Interpreter Design Pattern)指给定一个“语言”,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。这里所指的“语言”是指使用规定格式和语法的代码。
51 4
聊聊Java设计模式-解释器模式
|
1月前
|
设计模式 存储 前端开发
【设计模式】之解释器模式
解释器模式是一种用于解释特定语言或规则的表达式的行为设计模式。在前端开发中,解释器模式可以用于处理复杂的逻辑或规则,并将其转化为可执行的代码。它具有灵活性和可扩展性的优点,但也存在复杂性和性能问题的缺点。通过合理地应用解释器模式,可以提高代码的可读性和可维护性,实现更灵活和可扩展的功能。
49 1
|
1月前
|
设计模式 SQL 应用服务中间件
设计模式之解释器模式
设计模式之解释器模式
|
8月前
|
设计模式 C++
设计模式之解释器模式(C++)
设计模式之解释器模式(C++)
|
10月前
|
设计模式 算法 Java
设计模式-行为型模式:解释器模式
设计模式-行为型模式:解释器模式
|
设计模式 消息中间件 Java
一起来学设计模式之解释器模式
前言 目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本节给大家讲一下设计模式中的解释器模式,并结合实际业务场景给大家讲解如何使用~ 本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~ 解释器模式 解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的语法表示,并定义了一个解释器来解释这种语言中的表达式。通过使用解释器模式,可以轻松地扩展和修改语言的语法,从而使其更加灵活。
|
XML 设计模式 JSON
设计模式轻松学【二四】解释器模式
在生活中我们往往没听懂别人说的话,需要别人详细的解释一遍,才明白其中的意思。在学习Java的过程中我们不明白某个知识点,也需要有详细的解释才能让我们明白其中的韵味。对于编程语言来说也一样,JDK就是java运行提供的一种解释器,所以解释器模式就是去解析某个东西。
94 0
设计模式轻松学【二四】解释器模式
|
设计模式 Java
Java设计模式 ->解释器模式
Java设计模式 ->解释器模式
70 0