设计模式——解释器模式

更多内容,前往IT-BLOG

在软件开发中,会遇到有些问题多次重复出现,而且有一定的相似性和规律性。如果将它们归纳成一种简单的表达式(例如:正则表达式等),那么这些问题实例将是该表达式的一些句子,这样就可以用 “编译原理” 中的解释器模式来实现。

一、解释器模式基本介绍

【1】解释器模式(Interpreter Pattern): 是指给定一个语言(表达式),定义它的文法的一种表示。并定义一个解释器,使用该解释器来解释语言中的句子(表达式)。
【2】在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器。
【3】解释器模式是一种类行为型模式,其主要优点如下: ①、扩展性好,由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。②、容易实现,在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。
【4】解释器模式的主要缺点如下: ①、执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。②、会引起类膨胀。解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。③、可应用的场景比较少。在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。
【5】应用场景: ①、应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树 。②、一些重复出现的问题可以用一种简单的语言来表达。③、一个简单语法需要解释的场景。
【6】这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等。

二、解释器模式的结构与类图

解释器模式包含以下主要角色:
【1】抽象表达式(Abstract Expression)角色: 定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
【2】终结符表达式(Terminal Expression)角色: 是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
【3】非终结符表达式(Nonterminal Expression)角色: 也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
【4】环境(Context)角色: 通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
【5】客户端(Client): 主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

三、解释器模式案例分析

【1】抽象表达式: 抽象类表达式,通过 HashMap 键值对, 可以获取到变量的值。

/*** 抽象类表达式,通过HashMap 键值对, 可以获取到变量的值*/
public abstract class Expression {// a + b - c// 解释公式和数值, key 就是公式(表达式) 参数[a,b,c], value就是就是具体值// HashMap {a=10, b=20}public abstract int interpreter(HashMap<String, Integer> var);
}

【2】终结符表达式:

public class Calculator {// 定义表达式private Expression expression;// 构造函数传参,并解析public Calculator(String expStr) { // expStr = a+b// 安排运算先后顺序Stack<Expression> stack = new Stack<>();// 表达式拆分成字符数组char[] charArray = expStr.toCharArray();// [a, +, b]Expression left = null;Expression right = null;//遍历我们的字符数组, 即遍历  [a, +, b]//针对不同的情况,做处理for (int i = 0; i < charArray.length; i++) {switch (charArray[i]) {case '+': //left = stack.pop();// 从stack取出left => "a"right = new VarExpression(String.valueOf(charArray[++i]));// 取出右表达式 "b"stack.push(new AddExpression(left, right));// 然后根据得到left 和 right 构建 AddExpresson加入stackbreak;case '-': //left = stack.pop();right = new VarExpression(String.valueOf(charArray[++i]));stack.push(new SubExpression(left, right));break;default://如果是一个 Var 就创建要给 VarExpression 对象,并push到 stackstack.push(new VarExpression(String.valueOf(charArray[i])));break;}}//当遍历完整个 charArray 数组后,stack 就得到最后Expressionthis.expression = stack.pop();}public int run(HashMap<String, Integer> var) {//最后将表达式a+b和 var = {a=10,b=20}//然后传递给expression的interpreter进行解释执行return this.expression.interpreter(var);}
}

【3】非终结符表达式(抽象): 抽象运算符号解析器 这里,每个运算符号,都只和自己左右两个数字有关系。

/*** 抽象运算符号解析器 这里,每个运算符号,都只和自己左右两个数字有关系,* 但左右两个数字有可能也是一个解析的结果,无论何种类型,都是Expression类的实现类** @author Administrator**/
public class SymbolExpression extends Expression {protected Expression left;protected Expression right;public SymbolExpression(Expression left, Expression right) {this.left = left;this.right = right;}//因为 SymbolExpression 是让其子类来实现,因此 interpreter 是一个默认实现@Overridepublic int interpreter(HashMap<String, Integer> var) {// TODO Auto-generated method stubreturn 0;}
}

【4】非终结符表达式(实现一):

// 加法解释器
public class AddExpression extends SymbolExpression  {public AddExpression(Expression left, Expression right) {super(left, right);}//处理相加//var 仍然是 {a=10,b=20}..//一会我们debug 源码,就okpublic int interpreter(HashMap<String, Integer> var) {//super.left.interpreter(var) : 返回 left 表达式对应的值 a = 10//super.right.interpreter(var): 返回right 表达式对应值 b = 20return super.left.interpreter(var) + super.right.interpreter(var);}
}

【5】非终结符表达式(实现二):

public class SubExpression extends SymbolExpression {public SubExpression(Expression left, Expression right) {super(left, right);}//求出left 和 right 表达式相减后的结果public int interpreter(HashMap<String, Integer> var) {return super.left.interpreter(var) - super.right.interpreter(var);}
}

【6】客户端:

public class ClientTest {public static void main(String[] args) throws IOException {// TODO Auto-generated method stubString expStr = getExpStr(); // a+bHashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20}Calculator calculator = new Calculator(expStr);System.out.println("运算结果:" + expStr + "=" + calculator.run(var));}// 获得表达式public static String getExpStr() throws IOException {System.out.print("请输入表达式:");return (new BufferedReader(new InputStreamReader(System.in))).readLine();}// 获得值映射public static HashMap<String, Integer> getValue(String expStr) throws IOException {HashMap<String, Integer> map = new HashMap<>();for (char ch : expStr.toCharArray()) {if (ch != '+' && ch != '-') {if (!map.containsKey(String.valueOf(ch))) {System.out.print("请输入" + String.valueOf(ch) + "的值:");String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();map.put(String.valueOf(ch), Integer.valueOf(in));}}}return map;}
}

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

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

相关文章

科技创新领航 ,安川运动控制器为工业自动化赋能助力

迈入工业4.0时代&#xff0c;工业自动化的不断发展&#xff0c;让高精度运动控制成为制造业高质量发展的重要技术手段。北京北成新控伺服技术有限公司作为一家集工业自动化产品销售、系统设计、开发、服务于一体的高新技术企业&#xff0c;其引进推出的运动控制产品一直以卓越的…

基于Selenium+Python的web自动化测试框架

一、什么是Selenium&#xff1f; Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。Selenium主要包括三部分&#xff1a;Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE&#xff1a;Firefo…

海量数据处理数据结构之Hash与布隆过滤器

前言 随着网络和大数据时代的到来&#xff0c;我们如何从海量的数据中找到我们需要的数据就成为计算机技术中不可获取的一门技术&#xff0c;特别是近年来抖音&#xff0c;快手等热门短视频的兴起&#xff0c;我们如何设计算法来从大量的视频中获取当前最热门的视频信息呢&…

Windows下上帝模式的实现

在windows系统上有个特殊模式&#xff0c;那就是上帝模式&#xff0c;几乎包含了windows中所有的快捷方式&#xff0c;有很多小伙伴还不知道&#xff0c;让我们一起来实现这一操作吧&#xff01; 一、首先新建一个文件夹 二、接着将文件夹重命名&#xff0c;命名为以下代码&am…

考试面试轻松应对:技术人的备考宝库 | 开源专题 No.58

yangshun/tech-interview-handbook Stars: 97.9k License: MIT 这个项目是一个技术面试手册&#xff0c;提供了免费和精选的技术面试准备材料。它包括最佳实践问题、编码面试的常见问题、如何准备编程面试以及算法小抄等内容。该项目的核心优势和主要功能有&#xff1a; 提供…

楼宇管理新智慧:Panorama SCADA楼宇管理系统应用实例

一、背景介绍 楼宇管理系统旨在集中控制和监测楼宇运营&#xff0c;涵盖暖通空调&#xff08;HVAC&#xff09;、照明、电力系统、消防和安全系统等。通过直观的用户界面&#xff0c;用户得以实时监测和精准掌控这些系统&#xff0c;从而提升能源效率、确保设备正常运行&#…

PyCharm社区版如何创建Django项目并运行

一、配置Django环境 1、使用PyCharm打开一个普通的Python项目 2、为该项目配置Django环境 &#xff08;1&#xff09;点击"File"-"Settings" &#xff08;2&#xff09;点击"Project:项目名"-"Python Interpreter"-"号" &…

联手英特尔,释放星飞分布式全闪存储潜能

近日&#xff0c;英特尔官网发布了与 XSKY 星辰天合联手打造的解决方案&#xff0c;即 XSKY 的新一代全闪分布式存储系统 XINFINI&#xff0c;该存储系统采用英特尔 QAT 加速数据压缩/解压缩&#xff0c;从而大幅度提升存储系统性能。 全闪存储系统面临的解压缩挑战 在存储系统…

创建EasyCodeMybatisCodeHelperPro模板文件用于将数据库表生成前端json文件

在intellij idea中&#xff0c;通过插件EasyCodeMybatisCodeHelperPro&#xff0c;从现有的模板文件中选择一个复制粘贴&#xff0c;然后稍为修改&#xff0c;即可得到一个合适的模板文件。 现在的前端&#xff0c;越来越像后端。TypeScript替代了JavaScript&#xff0c;引入了…

LeetCode 232.用栈实现队列(详解) (๑•̌.•๑)

题目描述&#xff1a; 解题思路&#xff1a; 创建两个栈&#xff0c;一个用于入数据&#xff0c;一个用于出数据。分别是pushST和popST; 1.如果是入数据就直接入进pushST 2.如果是出数据&#xff0c;先检查popST中有无数据&#xff0c;如果有数据&#xff0c;就直接出。如果没…

Java--Spring项目生成雪花算法数字(Twitter SnowFlake)

文章目录 前言步骤查看结果 前言 分布式系统常需要全局唯一的数字作为id&#xff0c;且该id要求有序&#xff0c;twitter的SnowFlake解决了这种需求&#xff0c;生成了符合条件的这种数字&#xff0c;本文将提供一个接口获取雪花算法数字。以下为代码。 步骤 SnowFlakeUtils …

Linux Ubuntu 20.04.6 Intel WiFi6 Ax411 1690i Ax1690i Killer 解决无线网卡识别不出来问题

项目场景&#xff1a; 网卡型号&#xff1a;英特尔 Killer™ Wi-Fi 6E AX1690 i/s ubuntu 版本 uname -a Linux kuanli 5.15.0-91-generic #101~20.04.1-Ubuntu SMP Thu Nov 16 14:22:28 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux cat /proc/version Linux version 5.15.0-9…

docker 部署项目的操作文档,安装nginx

目录 1 部署环境检查2 相关知识点2.1 docker默认镜像存放地址2.2 docker 的镜像都是tar 包&#xff1f;2.3 Docker-compose 是直接使用镜像创建容器&#xff1f;2.4 Docker Compose down 就是将容器删除&#xff1f;2.5 删除&#xff0c;会删除挂载嘛2.6 DockerFile 和 docker …

Visual Studio 新特性:对 include 指令进行智能诊断

今天&#xff0c;我们很高兴地宣布新功能&#xff1a;#include 语言智能诊断。 此功能自 Visual Studio 2022 v17.9 预览版2 中可用。通过此新功能&#xff0c;您可以获取到有关每个 include 的引用和生成时间的详细信息&#xff0c;从而更好地了解 #include 指令的行为。 &g…

git仓库操作之一:git仓库修改名称

1 先修改“Project name"方法如下&#xff1a; 2 再修改“下载地址和下载后的项目名称”方法如下&#xff1a; 这样就修改完成了。

PhpPythonC++圆类的实现(OOP)

哎......被投诉了 &#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d; 其实也不是小编不更&#xff0c;这不是期末了吗&#xff08;zhaojiekou~~&#xff09;&#xff0c;而且最近学的信息收集和ctf感觉好像没找到啥能更的&#xff08;不过最经还是在考虑更一…

JAVA销售数据决策管理系统源码

JAVA销售数据决策管理系统源码 基于BS&#xff08;Extjs Strus2springhibernate Mysql&#xff09;的销售数据的决策支持 主要的功能有 系统功能具体内容包括基础资料、进货管理、出货管理、库存管理、决策分析、系统管理。

活水计划丨改善老年营养,促进老年健康

在中国乡村发展基金会、腾讯公益的支持下&#xff0c;1月10日上午辉县义工联合共济医院&#xff0c;在我市易地搬迁佳怡社区开展“乐伴银龄 社区共建”项目——“老年常见病健康知识讲座”活动。 通过制作宣传横幅、发放科普手册等方式&#xff0c;为协同推进健康中国和积极应对…

《AI基本原理和python实现》栏目介绍

一、说明 栏目《AI基本原理和python实现》的设计目的是为了实现相关算法的python编程。因为用python实现AI需对相关的python库进行全方位了解&#xff0c;本栏目基本包含了【机器学习】相关的经典算法&#xff0c;除此之外还包括了数据分析、时间序列等一些概念和相关python代码…

【SpringCloud Alibaba】Nacos Config配置管理与Gateway 网关

目录 一、Config 远程配置 1.1 config 介绍 1.2 bootstrap.yml 配置文件 二、Gateway 网关 2.1 gateway 介绍 2.2 gateway 使用 2.2.1 方式一 2.2.2 方式二&#xff08;动态路由&#xff09; 一、Config 远程配置 1.1 config 介绍 微服务意味着要将单体应用中的业务拆分…