03-JAVA设计模式-解析器模式

解释器模式

什么是解析器模式

在Java中,解释器模式(Interpreter Pattern)是一种行为设计模式,它给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。解释器模式主要用于处理包含特定语法规则的简单语言,如数学表达式、SQL语句、配置文件等。

解释器模式主要由以下角色组成:

  • 抽象表达式(Abstract Expression): 声明一个解释操作的接口,这个接口叫做解释操作。
  • 终结符表达式(Terminal Expression): 实现抽象表达式接口,该接口表示处理解释器语法中出现的终结符,终结符是语法中不可再分的最小单位。
  • 非终结符表达式(Nonterminal Expression): 同样实现抽象表达式接口,该接口表示处理解释器语法中出现的非终结符,非终结符是语法中的短语或句子,一般由终结符构成。
  • 环境角色(Context): 包含解释器之外的全局信息,一般是用来存储有关被解释句子的信息,如符号表的值等。
  • 客户端(Client): 构建(或给定)表示该文法的抽象语法树,并调用解释器的解释方法来执行程序。

注意:

解析器模式是一种不常用的设计模式

用于描述如何构成已个简单的语言解释器,主要用于使用面相对象语言开发编译器和解释器设计

当我们需要开发一种新的语言是,可以考虑使用

实际开发中尽量不要使用解释器模式,后期维护忽悠很大的麻烦,在项目中,可以使用Jruby,Groovy,java的js引擎来替代解释器的作用,弥补java语言的不足

案例

实现通过输入字符串10+30-25计算得到最终的结果

UML

在这里插入图片描述

实现步骤:

  • 定义解释接口及返回值Expression
  • 创建具体的表达式-数字NumberExpression
  • 创建具体的表达式-符号OperatorExpression
  • 创建具体的表达式-加法AddExpression
  • 创建具体的表达式-减法SubtractionExpression
  • 创建解析类ExpressionParser,实现表达式解析,且用队列存储解析后的表达式,提供interpret()方法执行表达式

实现代码

Expression.java

// 抽象表达式接口
public interface Expression {// 定义解释接口及返回值int interpret();
}

NumberExpression.java

// 具体的表达式-数字
public class NumberExpression implements Expression{// 定义接收值private Integer value;public NumberExpression(Integer value) {this.value = value;}@Overridepublic int interpret() {return value;}
}

OperatorExpression.java

// 具体的表达式-符号
public class OperatorExpression implements Expression{// 定义接收值private char value;public OperatorExpression(char value) {this.value = value;}@Overridepublic int interpret() {return value;}
}

AddExpression.java

// 具体的表达式-加法
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();}
}

Expression.java

// 具体的表达式-减法
public class SubtractionExpression implements Expression{// 解析器左侧表达式private Expression left;// 解析器右侧表达式private Expression right;public SubtractionExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret() {return left.interpret() - right.interpret();}
}

ExpressionParser.java

import java.util.ArrayDeque;
import java.util.Deque;// 解析器类
public class ExpressionParser{private String expression;private int index = 0;private Deque<Expression> queue = new ArrayDeque<Expression>();public ExpressionParser(String expression) {this.expression = expression;parse();}// 解析表达式public void parse(){// 判断是否连续数字boolean markDigit = false;// 判断是否连续运算符boolean markOperation = false;while (index < expression.length()){char c = expression.charAt(index);// 字符判断if(Character.isDigit(c) && !markDigit){markDigit = true;markOperation = false;parseNumber();continue;}else if((c == '+' || c == '-') && !markOperation){markDigit = false;markOperation = true;parseOperation();} else {throw new RuntimeException("输入字符错误: " + c);}index++;}}// 解析数字private void parseNumber() {StringBuilder sb = new StringBuilder();while (index < expression.length() && Character.isDigit(expression.charAt(index))) {sb.append(expression.charAt(index));index++;}int number = Integer.parseInt(sb.toString());queue.offer(new NumberExpression(number));}// 解析符号private void parseOperation() {queue.offer(new OperatorExpression(expression.charAt(index)));}// 计算public int interpret() {Expression result = null;int len = queue.size();for (int i = 0; i < len; i++) {Expression pop = queue.poll();if(result == null){result = pop;}else if (pop instanceof OperatorExpression &&  pop.interpret() == '+') {result = new AddExpression(result, queue.poll());i++;}else if (pop instanceof OperatorExpression &&  pop.interpret() == '-') {result = new SubtractionExpression(result, queue.poll());i++;}else {throw new RuntimeException("表达式异常");}}return result.interpret();}
}

TestClient.java

// 测试
public class TestClient {public static void main(String[] args) {String expression = "10+30-25";ExpressionParser parser = new ExpressionParser(expression);System.out.println("Result: " + parser.interpret());}
}

执行结果:

在这里插入图片描述

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

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

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

相关文章

Linux提权--SUID提权内核漏洞本地用户提权

免责声明:本文仅做技术交流与学习,请不要乱搞破坏... 目录 SUID提权 漏洞成因 提权过程: 手工命令探针: 参考利用&#xff1a; 脚本探针: LinEnum.sh traitor linuxprivchecker等等... Linux命令的利用: find命令 利用nc反弹 利用python反弹--棱角 内核漏洞本地用…

电磁兼容(EMC):生产的ESD防护要点及措施

目录 1. 接地和连接系统 2. 操作员及工作区域 3. 地板 4. 座椅 5. 防静电车间 早期电子产品出现质量问题有80%的问题都是生产过程静电所引起的。随着ESD的管理程序系统的普及&#xff0c;ESD问题相当减小很多。例如当今的S20.20静电控制程序产生于IBM内部审核和控制系统。…

打不完!真的打不完!海量用户线索车企该怎么办?用AI!

当车企面临海量用户线索&#xff0c;怎么找到精准用户&#xff1f;大量的电话根本打不完&#xff0c;这种情况怎么办&#xff1f;建议借助AI&#xff0c;降本增效。下面以某车企为例来帮助大家解决这个难题&#xff01; 某车企面临的问题主要有三点 第一&#xff1a;车企有来自…

罗德与施瓦茨矢量网络分析仪ZNB20相位一致性

矢量网络分析仪(VNA)是电子测量领域中非常重要的一类仪器,广泛应用于射频和微波电路的测试与分析。其中,德国罗德与施瓦茨公司生产的ZNB20型号是一款性能出色的矢量网络分析仪,深受业内人士的青睐。本文将重点介绍ZNB20在相位测量方面的特点和优势,为用户提供全面的使用参考。 …

微信红包架构

文章目录 包发抢拆抢红包——拆包算法——要解决并发问题那怎么做呢&#xff1f;——预分配红包预分配怎么实现呢&#xff1f;redis集群解决日均百亿级但微信没有用预分配方案哦——内存消耗过大——cas查询红包领取记录会很频繁的查询&#xff0c;从redis中查询hash&#xff0…

软考易错题

一.数据库的设计过程&#xff0c;按照规范的设计方法&#xff0c;一般分为以下六个阶段: ①需求分析:分析用户的需求&#xff0c;包括数据、功能和性能需求; ②概念结构设计:主要采用E-R模型进行设计&#xff0c;包括画E- R图; ③逻辑结构设计:通过将E-R图转换成表&#xff…

android11 加入GMS后修改launcher图标顺序

使用的launcher \vendor\partner_gms\apps\SearchLauncher 使用的布局 vendor\partner_gms\apps\GmsSampleIntegration vendor\partner_gms\apps\GmsSampleIntegration\res_dhs_full\xml <folder title"string/google_folder_title" container"-101"…

DOS比较运算符及常用操作

目录 rem 比较运算符:事例批处理 数值计算与大小比较注释比较大小if语句while循环输出到屏幕输出到文本读取文本到剪切板删除文件暂停关闭回显 rem 比较运算符: EQU - 等于 NEQ - 不等于 LSS - 小于 LEQ - 小于或等于 GTR - 大于 GEQ - 大于或等于 例如 if not %in%2 goto 2 如…

Spring 之 MatchingStrategy

在Spring框架的上下文中&#xff0c;MatchingStrategy 特别指代处理URL路径匹配的方法策略。这是Spring MVC中一个关键的概念&#xff0c;用于决定HTTP请求的URL路径应当如何与控制器&#xff08;Controller&#xff09;中的请求映射&#xff08;RequestMapping&#xff09;进行…

Google Cloud 的 AI 超计算机架构的新增功能

跳转到内容 云 博客 解决方案与技术 生态系统 开发者与从业者 借助 Google Cloud 进行转型 联系销售人员 免费开始使用 计算 文章来自于谷歌云 Google Cloud 的 AI 超计算机架构的新增功能 2024 年 4 月 10 日 https://storage.googleapis.com/gweb-cloudblog-publish/images/…

字符串的格式化输出、索引和切片以及7个常用的函数的使用

1.字符串的格式化输出: f-string 是一种方便的字符串格式化方式&#xff0c;可以直接在字符串中嵌入变量。2. name "Alice" age 30 print(f"My name is {name} and I am {age} years old.") 2.索引和切片: 索引和切片是用来访问字符串中的特定字符或…

Blob对象实现文件下载

首先&#xff0c;要有下载按钮 <a download onClick{()> downloadAttentment(data)}>下载</a>其次&#xff0c;定义下载function // 此处去处理 blob 对象 const downloadStreamByATag (data, suffix, name) > {if (suffix void 0) { suffix xls; }if (…

Python数据结构与算法(1):将序列分解为单独的变量

问题 现在有一个包含 N 个元素的元组或者是序列&#xff0c;怎样将它里面的值解压后同时赋值给 N 个变量&#xff1f; 解决方案 任何的序列&#xff08;或者是可迭代对象&#xff09;可以通过一个简单的赋值操作来分解为单独的变量。 唯一的要求就是变量的总数和结构必须与序…

JAVASE 数组相关知识

递归 A方法调用B方法&#xff0c;我们很容易理解 递归就是:A方法调用A方法&#xff0c;即自己调用自己 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解&#xff0c;递归策略只需少量的程序就可…

一个人可能代表一群人

最近有个小伙伴问他是做货代的&#xff0c;怎么能找到自己的客户&#xff1f;刚看到这个问题的时候&#xff0c;觉得这个不属于自己的范围&#xff0c;因为自己不是做货代的&#xff0c;怎么知道他们怎么工作&#xff0c;怎么去搜索客户呢&#xff1f; 但是仔细想来&#xff0…

【Java EE】日志框架(SLF4J)与门面模式

文章目录 &#x1f340;SLF4j&#x1f333;门面模式(外观模式)&#x1f338;门面模式的定义&#x1f338;门面模式的模拟实现&#x1f338;门面模式的优点 &#x1f332;关于SLF4J框架&#x1f338;引入日志门面 ⭕总结 &#x1f340;SLF4j SLF4J不同于其他⽇志框架,它不是⼀个…

跟TED演讲学英文:AI isn‘t as smart as you think -- but it could be by Jeff Dean

AI isn’t as smart as you think – but it could be Link: https://www.ted.com/talks/jeff_dean_ai_isn_t_as_smart_as_you_think_but_it_could_be Speaker: Jeff Dean Jeffrey Adgate “Jeff” Dean (born July 23, 1968) is an American computer scientist and software…

【服务器部署篇】Linux下快速安装Jenkins

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

微前端micro-app 子应用 调用父应用方法

参考&#xff1a;micro-app官方文档 场景描述 父应用存储一套vuex数据&#xff0c;其中包含登录信息token等&#xff0c;登录信息透传给子应用使用。 当子应用中的接口返回“登录失效”时&#xff0c;需要清空父应用vuex中的登录相关信息&#xff0c;并且跳转到登录页面。 原…

网站建设企业网站优化

近年来&#xff0c;随着互联网的迅速发展&#xff0c;企业网站已经成为了企业展示自我形象与实力的重要载体之一。然而&#xff0c;单单拥有一个美观、简洁的企业网站并不能让企业在竞争激烈的市场中脱颖而出。因此&#xff0c;在建设企业网站的过程中&#xff0c;我们需要将企…