设计模式----解释器模式
一、简介
解释器模式使用频率并不高,通常用来构建一个简单语言的语法解释器,它只在一些非常特定的领域被用到,比如编译器、规则引擎、正则表达式、sql解析等。
解释器模式是行为型设计模式之一,它的原始定义为:用于定义语言语法规则表示,并提供解释器来处理句子中的语法。
我们通过一个例子来解释下解释器模式,假设我们设计一个软件来进行加减计算,我们第一想法就是使用工具类,提供对应的加法和减法的工具方法。
public int add(int a,int b){
return a+b;
}public int add(int a,int b,int c){
return a+b+c;
}
......
上面的形式比较单一、有限如果形式变化非常多,这就不符合要求,因为加法和减法运算,两个运算符数组可以有无限种合作方式,比如1+3+2+1-5....
解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。
二、结构

解释器模式由以下几种角色组成:
①抽象表达式角色:定义解释器的接口,约定解释器的操作,主要包含解释方法interoret
②终结符表达式角色:用来实现文发中与终结符相关的操作,文法中的每一个终结符都有一个具体的终结符表达式与之对应
③非终结符表达式:用来实现文法中与非终结符相关的操作,文法中每条规则都对应一个非终结符表达式
④上下文类:通常包含各个解释器需要的数据或者是公共的功能,一般用来传递所有解释器共享的数据。
三、实现
我们定义一个进行加减乘除计算的语言,语法规则如下:
①运算符只包含加减乘除,并且没有优先级概念
②表达式中,先写数字后写运算符,空格隔开
// 表达式接口
public interface Expression {int interpret();
}// 加法解释器
public class AddExpression implements Expression {private Expression left;private Expression right;public AddExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret() {return left.interpret() + right.interpret();}
}// 减法解释器
public class SubtractExpression implements Expression {private Expression left;private Expression right;public SubtractExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret() {return left.interpret() - right.interpret();}
}// 乘法解释器
public class MultiplyExpression implements Expression {private Expression left;private Expression right;public MultiplyExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret() {return left.interpret() * right.interpret();}
}// 除法解释器
public class DivideExpression implements Expression {private Expression left;private Expression right;public DivideExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret() {try {return left.interpret() / right.interpret();} catch (ArithmeticException e) {System.out.println("除数不能为0");return -1;}}
}// 数字解释器
public class NumberExpression implements Expression {private int number;public NumberExpression(int number) {this.number = number;}@Overridepublic int interpret() {return number;}
}
现在我们可以使用这些类来解析四则运算表达式了。例如,对于表达式 “1 + 2 * 3 - 4 / 2”我们可以使用以下代码来解析该表达式:
Expression expression = new SubtractExpression(new AddExpression(new NumberExpression(1),new MultiplyExpression(new NumberExpression(2),new NumberExpression(3))),new DivideExpression(new NumberExpression(4),new NumberExpression(2)));
int result = expression.interpret();
System.out.println("计算结果为:" + result);
四、总结
优点
①易于改变可扩展文法,因为在解释器模式中实用类来表示语言的文法规则的,因此可以通过继承等机制改变或扩展文法,每一个文法规则都可以表示为一个类,因此我们可以快速的实现一个迷你的语言
②实现文法比较容易,在抽像语法术中每一个表达式节点的实现方式都是相似的,这些代码不特别复杂
③增加新的解释表达式比较方便,如果用户增加新的解释表达式,只需要对应增加一个新的表达式类就可以,原有的表达式不需修改,符合开闭原则
缺点
①对于复杂文法难以维护,在解释器中,一条规则至少要定义一个类,因此一个语言中有太多的文法规则,那么就会使类的个数急剧增加,导致系统的维护难以管理。
②执行效率低,在解释器模式中,大量的使用循环和递归调用,所以复杂的句子执行起来比较繁琐
使用场景
①当语言的文法比较简单时,并且执行的效率不是关键问题的时候
②当问题重复出现,且可以用一种简单的语言来表达
③当一个语言要解释执行,并且语言中的句子可以表示为一个抽象的语法树的时候。
相关文章:
设计模式----解释器模式
一、简介 解释器模式使用频率并不高,通常用来构建一个简单语言的语法解释器,它只在一些非常特定的领域被用到,比如编译器、规则引擎、正则表达式、sql解析等。 解释器模式是行为型设计模式之一,它的原始定义为:用于定义…...
Linux常用命令(一):Conda、RPM、文件权限、apt-get(更新中...
文章目录 一、Conda二、RPM三、文件权限四、apt-get 一、Conda Conda是一个开源的软件包管理系统和环境管理系统,用于安装和管理软件包及其依赖项。它主要用于Python编程语言,但也可以用于其他语言的项目。Conda可以帮助用户创建不同版本的Python环境&a…...
3 个适用于 Mac 电脑操作的 Android 数据恢复最佳工具 [附步骤]
在当今的数字时代,无论是由于意外删除、系统故障还是其他原因,从 Android 设备中丢失数据不仅会带来不便,而且会造成非常严重的后果。特别是对于Mac用户来说,从Android手机恢复数据是一个很大的麻烦。幸运的是,随着许多…...
日志服务 SLS 深度解析:拥抱云原生和 AI,基于 SLS 的可观测分析创新
云布道师 10 月 31 日,杭州云栖大会上,日志服务 SLS 研发负责人简志和产品经理孟威等人发表了《日志服务 SLS 深度解析:拥抱云原生和 AI,基于 SLS 的可观测分析创新》的主题演讲,对阿里云日志服务 SLS 产品服务创新以…...
MinIO客户端之rm
MinIO提供了一个命令行程序mc用于协助用户完成日常的维护、管理类工作。 官方资料 mc rm 删除指定的对象。 准备待删除的对象,查看对象,命令如下: ./mc ls local1/bkt2/控制台的输出,如下: [2023-12-16 01:52:54 …...
【Linux笔记】文件和目录操作
🍎个人博客:个人主页 🏆个人专栏:Linux学习 ⛳️ 功不唐捐,玉汝于成 目录 前言 命令 ls (List): pwd (Print Working Directory): cp (Copy): mv (Move): rm (Remove): 结语 我的其他博客 前言 学习Linux命令…...
Vue-router 中hash模式和history模式的区别
Vue-router 中hash模式和history模式的区别 在通过vue-cli创建项目的时候,出现: 于是,去Google一遍。。 vue-router的model有两种模式:hash模式和history模式。 hash模式和history模式的不同 最直观的区别就是在url中 hash 带了一个很丑的…...
Debian在升级过程中报错
当我们在升级的过程中出现如下报错信息 报错信息如下所示: The following signatures couldnt be verified because the public key is not available: NO_PUBKEY ED444FF07D8D0BF6 W: GPG error: http://mirrors.jevincanders.net/kali kali-rolling InRelease: …...
IOS开发问题记录
1. xcode上传app store connect后testflight没有可构建版本的原因 查看你的邮箱, 里面有原因提示 一般为使用了某些权限, 但是plist没有声明 2. xcode 修改display name后名字并没有改变 原因是并没有修改到plist的CFBundleDisplayName的字段 将CFBundleDisplayName的值修改…...
数据流图_DFD图_精简易上手
数据流图(DFD)是一种图形化技术,它描绘信息流和数据从输人移动到输出的过程中所经受的变换。 首先给出一个数据流图样例 基本的四种图形 直角矩形:代表源点或终点,一般来说,是人,如例图的仓库管理员和采购员圆形(也可以画成圆角矩形):是处理,一般来说,是动作,是动词名词的形式…...
使用 Xcode 创建一个新的项目并运行
启动 Xcode: 打开你的 Mac,然后启动 Xcode。你可以在应用程序文件夹中找到它,或者使用 Spotlight 搜索。 创建新项目: 当 Xcode 启动时,选择 “Create a new Xcode project”(创建一个新的 Xcode 项目)。 在项目模板…...
教师未来前景发展
教师是一个光荣而重要的职业,他们承担着培养下一代的责任和使命。随着社会的不断发展和变化,教师的前景也在不断扩大和改变。本文将探讨教师未来的前景发展,并提供一些思考和建议。 首先,教师的就业前景将继续扩大。随着人口的增长…...
【华为机试】2023年真题B卷(python)-采样过滤
一、题目 题目描述: 在做物理实验时,为了计算物体移动的速率,通过相机等工具周期性的采样物体移动能离。由于工具故障,采样数据存在误差甚至相误的情况。需要通过一个算法过滤掉不正确的采样值,不同工具的故意模式存在…...
编译opencv和opencv_contrib
1 下载源码 下载opencv源码https://github.com/opencv/opencv 下载opencv源码https://github.com/opencv/opencv_contrib 2 开始编译 构建需要下载ffmpeg的包,cmake构建时会自动下载,但是比较满,这里可以从下面链接直接下载 https://downloa…...
每次maven刷新jdk都要重新设置
pom.xml <java.version>17</java.version> 改为<java.version>1.8</java.version>...
《PySpark大数据分析实战》-18.什么是数据分析
📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…...
【小白攻略】php 小数转为百分比,保留两位小数的函数
php 小数转为百分比 首先,最简单直观的方法是利用PHP内置的number_format函数。该函数可以对一个数字进行格式化,并可以设置小数点后的精度。通过将小数乘以100,再用number_format函数将结果格式化为百分比形式,即可达到将小数转为…...
electron GPU process isn‘t usable. Goodbye
最近再使用electron的时候总是报错打不开,记录一下这个问题的解决方法; // 再主进程中添加下面的即可 app.commandLine.appendSwitch(no-sandbox);官网看了下:https://www.electronjs.org/zh/docs/latest/api/command-line-switches –no-sa…...
ApsaraMQ Serverless 演进之路,助力企业降本
作者:家泽 ApsaraMQ 与时俱进,砥砺前行 阿里云消息队列从诞生开始,至今已有十余年。今年,阿里云消息产品全面品牌升级为 ApsaraMQ,与时俱进,砥砺前行。 2012 年,RocketMQ 诞生于集团内部&…...
redis 从0到1完整学习 (六):Hash 表数据结构
文章目录 1. 引言2. redis 源码下载3. dict 数据结构4. 哈希表扩容与 rehash5. 参考 1. 引言 前情提要: 《redis 从0到1完整学习 (一):安装&初识 redis》 《redis 从0到1完整学习 (二):red…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

