解释器模式

news2024/9/22 15:49:46

文章目录

    • 解释器模式
      • 1.解释器模式的本质
      • 2.何时选用解释器模式
      • 3.优缺点
      • 4.解释器模式的结构
      • 5.实现
        • 计算器加减操作

解释器模式

当想解析一个文件或者其他内容时,可以根据规律自己定义一种文法,并定义一个解释器,然后解析这种文法,以达到解析文件或其他内容的效果

1.解释器模式的本质

解释器模式的本质:分离实现,解释执行。

解释器模式通过一个解释器对象处理一个语法规则的方式,把复杂的功能分离开;然后选择需要被执行的功能,并把这些功能组合成为需要被解释执行的抽象语法树;再按照抽象语法树来解释执行,实现相应的功能。

2.何时选用解释器模式

建议在以下情况中选用解释器模式。

当有一个语言需要解释执行,并且可以将该语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式。

在使用解释器模式的时候,还有两个特点需要考虑,一个是语法相对应该比较简单,太复杂的语法不适合使用解释器模式;另一个是效率要求不是很高,对效率要求很高的情况下,不适合使用解释器模式。

3.优缺点

解释器模式有以下优点。.

  • 易于实现语法
    在解释器模式中,一条语法规则用一个解释器对象来解释执行。对于解释器的实现来讲,功能就变得比较简单,只需要考虑这一条语法规则的实现就可以了,其他的都不用管。

  • 易于扩展新的语法
    正是由于采用一个解释器对象负责一条语法规则的方式,使得扩展新的语法非常容易。扩展了新的语法,只需要创建相应的解释器对象,在创建抽象语法树的时候使用这个新的解释器对象就可以了。

解释器模式的缺点是不适合复杂的语法。

如果语法特别复杂,构建解释器模式需要的抽象语法树的工作是非常艰巨的,再加上有可能会需要构建多个抽象语法树。所以解释器模式不太适合于复杂的语法,对于复杂的语法,使用语法分析程序或编译器生成器可能会更好一些。

4.解释器模式的结构

在这里插入图片描述

  • AbstractExpression:定义解释器的接口,约定解释器的解释操作。
  • TerminalExpression:终结符解释器,用来实现语法规则中和终结符相关的操作,不再包含其他的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的叶子对象,可以有多种终结符解释器。
  • NonterminalExpression:非终结符解释器,用来实现语法规则中非终结符相关的操作,通常一个解释器对应一个语法规则,可以包含其他的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的组合对象。可以有多种非终结符解释器。
  • Context:上下文,通常包含各个解释器需要的数据或是公共的功能。
  • Client:客户端,指的是使用解释器的客户端,通常在这里将按照语言的语法做的表达式转换成为使用解释器对象描述的抽象语法树,然后调用解释操作。

5.实现

在这里插入图片描述

解释器模式的核心思想是:定义一种文法,并定义一个解释器,使用该解释器来解释这个文法。
文法:可以将其理解为一种规则,就好比汉语中一句话必须由“主谓宾”三者构成一样。下面的文法是加减操作,只要是加减操作下面的解释器就可以进行解析。

计算器加减操作

实现一个计算器的加减操作

1.解释器接口及其实现类

/**
 * @description:解释器接口
 */
public interface Expression {

    /**
     * 解析表达式
     * @return
     */
    int interpret();

}

/**
 * @description:数值解释器
 */
public class NumExpression implements Expression {

    private int value;

    public NumExpression(int value) {
        this.value = value;
    }
    
    @Override
    public int interpret() {
        return this.value;
    }
    
}

/**
 * @description:加法解释器
 */
public class AddExpression implements Expression {

    public Expression left;
    public Expression right;

    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return this.left.interpret() + this.right.interpret();
    }
}

/**
 * @description:减法解释器
 */
public class SubExpression implements Expression {

    public Expression left;
    public Expression right;

    public SubExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return this.left.interpret() - this.right.interpret();
    }
}

2.上下文类

/**
 * @description:计算器类(上下文)
 */
public class Calculator {

    //栈
    private Stack<Expression> stack = new Stack<>();

    /**
     * @author conggq
     * @description:解释文法方法
     * @createTime 2022/11/30 13:06
     */
    public int parse(String expression) {
        String[] elements = expression.split(" ");
        Expression leftExpr, rightExpr;

        for (int i = 0; i < elements.length; i++) {
            String operator = elements[i];
            if (("+".equals(operator) || "-".equals(operator))) {
                leftExpr = this.stack.pop();
                rightExpr = new NumExpression(Integer.valueOf(elements[++i]));
                if ("+".equals(operator)) {
                    this.stack.push(new AddExpression(leftExpr, rightExpr));
                } else if ("-".equals(operator)) {
                    this.stack.push(new SubExpression(leftExpr, rightExpr));
                }
            } else {
                NumExpression numInterpreter = new NumExpression(Integer.valueOf(elements[i]));
                this.stack.push(numInterpreter);
            }
        }
        //等价于new SubExpression(new AddExpression(new NumExpression(10), new NumExpression(30)), new NumExpression(20)).interpret()
        return this.stack.pop().interpret();
    }

}

3.测试类

/**
 * @description:测试类
 */
public class Client {

    public static void main(String[] args) {
        System.out.println("result: " + new Calculator().parse("10 + 30 - 20"));
        System.out.println("result: " + new SubExpression(new AddExpression(new NumExpression(10), new NumExpression(30)), new NumExpression(20)).interpret());
    }

}

4.结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB-自定义函数拟合(fittype-高斯拟合)

在回归拟合分析时,一般情况下,MATLAB会直接提供常用的类型,用fittype创建拟合模型,至于MATLAB具体提供了哪些模型,参见帮助“List of library models for curve and surface fitting”,如果库中没有自己想要的拟合表达式形式,可以自己进行定义,具体介绍如下: 1. fitty…

嵌入式:ARM间接寻址、变址寻址与多寄存器寻址

文章目录寄存器间接寻址基址加偏址寻址&#xff08;变址寻址&#xff09;偏移地址传送数据类型块拷贝寻址&#xff08;多寄存器寻址&#xff09;块拷贝寻址示例寄存器间接寻址 寄存器间接寻址就是以寄存器中的值作为操作数的地址&#xff0c;而操作数本身存放在存储器中。例如…

尚医通 (三十七) --------- 定时任务与统计

目录一、就医提醒1. 搭建定时任务模块 service-task2. 添加就医提醒处理二、预约统计1. ECharts2. 获取医院每天平台预约数据接口3. 添加 feign 方法4. 搭建 service-statistics5. 前端展示一、就医提醒 我们通过定时任务&#xff0c;每天 8 点执行&#xff0c;提醒就诊。 1.…

[附源码]Python计算机毕业设计Django校园招聘系统设计

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Android Accessibility知识分享

工具 工欲善其事&#xff0c;必先利其器。下面我们介绍一下工具来发现我们的accessibility问题。感谢这篇文章的分享&#xff1a;https://www.kodeco.com/240-android-accessibility-tutorial-getting-started Lint&#xff1a;这个工具是google提供的&#xff0c;在android …

python--面向对象以及其三大特性(封装、继承、多态)

文章目录前言一、面向过程二、 面向对象三、面向对象的三大特性一、封装二、继承私有属性和私有方法三、多态四、高级特性单例模式前言 这一节主要学习面向对象以及面向对象的三大特性&#xff1a;封装、继承、多态&#xff1b;还有高级特性&#xff1a;类方法、静态方法、pro…

【OpenFeign】【源码+图解】【二】注册OpenFeign接口的实例

【OpenFeign】【源码图解】【一】HelloWorld及其工作原理 目录3. 注册OpenFeign接口的实例3. 注册OpenFeign接口的实例 从HelloWorld中我们看到需要显示加入**EnableFeignClients注解才能开启openFeign的功能&#xff0c;因此它就成为我们分析openFeign**的入口&#xff0c;先…

Chrony时间同步服务

目录 一、时间同步 1.概念 2.时间同步在运维工作中的作用 3.时间同步完成方法 &#xff08;1&#xff09;NTP时间服务&#xff08;centos 6 &#xff09; &#xff08;2&#xff09;Chrony时间服务 二、Chrony时间服务 1.Chrony介绍 2.Chrony的优点 三、Chrony安装 …

逻辑回归(Logistic Regression)原理及过程

目录 一&#xff1a;逻辑回归简介 二&#xff1a;逻辑回归原理 三&#xff1a;逻辑回归 损失函数 四&#xff1a;逻辑回归 梯度下降算法 五&#xff1a;逻辑回归 过程 一&#xff1a;逻辑回归简介 Logistic模型是1938年Verhulst-Pearl在修正非密度方程时提出来的&#xf…

算法刷题打卡第49天:排序数组---计数排序

排序数组 难度&#xff1a;中等 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 示例 1&#xff1a; 输入&#xff1a;nums [5,2,3,1] 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;nums [5,1,1,2,0,0] 输出&#xff1a;[0,0,1,1,2,5]计数排…

我与世界杯的故事——达利奇:铜牌闪耀着金光

目录 克罗地亚球队的历史 奇迹出现 心得总结 克罗地亚球队的历史 克罗地亚球队拥有悠久的历史&#xff1a; 1998年首次亮相法国世界杯&#xff0c;克罗地亚就以季军的战绩惊艳众人。 2018年的俄罗斯世界杯&#xff0c;虽然格子军团在决赛中不敌强大的法国&#xff0c;遗憾地…

<Linux进程通信之共享内存>——《Linux》

目录 一、system V共享机制 1.共享内存示意图 2.共享内存数据结构 3.共享内存函数 3.1shmget函数 3.2 shmat函数 3.3 shmdt函数 3.4 shmctl函数 3.5 实例代码&#xff1a; 3.6 结果演示&#xff1a; 4. 创建共享内存 5. 基于共享内存与管道进行访问控制的共享内存读…

(P4)Python plt显示图像

Python plt显示图片 本地可以显示&#xff0c;服务器操作不太行。 plt.plot(x,y) plt.imshow(image) plt.show() # 显示图像&#xff08;曲线/图片都需要这一行&#xff09; plt.savefig(xx.png) # 保存图片 fig.savefig(xx.png) 功能相同 # 保存图片在本地执行失败&#xff…

Elasticsearch学习笔记

Elasticsearch学习笔记 ----第1章 Elasticsearch概述-01-开篇02-技术选型03-教学大纲-第2章 Elasticsearch入门-04-入门-环境准备05-入门-RESTful & JSON06-入门-Postman客户端工具07-入门-倒排索引08-入门-HTTP-索引-创建09-入门-HTTP-索引-查询 & 删除10-入门-HTTP-…

Linux 调试之 TRACE_EVENT(一)

文章目录前言一、TRACE_EVENT简介二、TRACE_EVENT() 结构2.1 TRACE_EVENT简介2.2 trace_sched_switch示例2.2.1 Name2.2.2 Prototype2.2.3 Arguments2.2.4 Structure2.2.5 Assignment2.2.6 Print2.3 Format file2.3.1 tracing/events/2.3.2 perf2.3.3 bpftrace2.3.4 bcc2.3.5 S…

逻辑回归 鸢尾花分类预测

目录 一&#xff1a;加载数据 二&#xff1a;数据集划分 三&#xff1a;选择算法 四&#xff1a;网格模型 超参数最优解 五&#xff1a;鸢尾花分类预测 六&#xff1a;预测与实际比对 七&#xff1a;完整源码分享 一&#xff1a;加载数据 from sklearn.datasets import…

Jenkins启动项目时报错问题

问题 在工作中使用jenkins进行项目部署启动时遇到问题&#xff0c;项目构建成功但是发布时一直显示时间增加&#xff0c;但是项目本身并没有问题&#xff0c;使用传统方法部署项目也能正常启动。报错如下图所示&#xff1a; 解决方法 是由于jenkins文件中打印日志的问题&am…

PayPal,Stripe,Square轮询支付系统

轮询展示 展示我们轮询的页面 轮询套餐 根据不同的用户和需求&#xff0c;可以选择不同的套餐 普通版 1500元 1年 1个用户 支持Paypal/Stripe 不限制A站个数 不限制B站个数 不限制提交模式 订单管理 物流管理 风控管理 必要的网站数据处理 24小时远程协助 开始…

springcloud服务消费与熔断

今天与大家分享服务消费与熔断&#xff0c;就是说当我们服务消费者转发到服务生产者时&#xff0c;如果有那一步出现了问题或者error&#xff0c;可以进行服务熔断&#xff08;服务降级&#xff09;&#xff0c;为了补救系统问题&#xff0c;不让用户使用时看见error报错信息&a…

《Java》String、StringBuffer、StringBuilder有什么区别?

目录 String StringBuffer StringBuilder 总结 ps&#xff1a;昨天在讨论完String的不可变性之后突然想要做一份总结笔记&#xff0c;总结一下String、StringBuffer、StringBuilder的区别 String String是Java中的基础类&#xff0c;提供了各种构造和对字符串的基本操作&am…