设计模式(23)解释器模式

一、介绍:

1、定义:解释器(Interpreter)模式是一种对象的行为模式。给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

2、组成结构:


(1)AbstractExpression(抽象表达式):约定解释器的解释操作,主要是一个interpret()方法。这个接口作为抽象语法树中所有节点(即终结符表达式和非终结符表达式)所共享

public abstract class AbstractExpression {public abstract void interpret(Context context);
}

(2) TerminalExpression(终结符表达式):用来实现文法中和终结符相关的解释操作,不再包含其它的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的叶子对象,可以有多种终结符解释器。

public class TerminalExpression extends AbstractExpression{@Overridepublic void interpret(Context context) {System.out.println("终结符解释器");}
}

(3)NonterminalExpression(非终结表达式):用来实现文法中和非终结符相关的解释操作,通常一个解释器对应一个语法规则,可以包含其它的解释器,如果用组合模式来构建抽象语法树的话,就相当于组合模式中的组合对象,可以有多种非终结符解释器。公式R=R1+R2中,R1、R2为终结符表达式,+为非终结表达式(其后需要跟随一个终结符表达式)。

public class NonterminalExpression extends AbstractExpression{@Overridepublic void interpret(Context context) {System.out.println("非终结符解释器");}
}

(4) Context类(包含解释器之外的一些全局信息):也称“上下文”,常用HashMap来代替,通常包含解释器之外的一些全局信息(解释器需要的数据,或是公共的功能)。

public class Context {private String input;private String output;//Get、Set方法省略
}

客户端,构建文法表示的抽象语法树(Abstract Syntax Tree),该抽象语法树由终结符表达式和非终结符表达式的实例装配而成),并调用解释操作interpret()方法。 

Context context = new Context();List<AbstractExpression> list = new ArrayList<AbstractExpression>();list.add(new TerminalExpression());list.add(new NonterminalExpression());list.add(new TerminalExpression());list.add(new NonterminalExpression());for (AbstractExpression abstractExpression : list) {abstractExpression.interpret(context);}

3、适用场景:解释器模式似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个语言的文法。建议在以下情况中选用解释器模式: 当有一个语言需要解释执行,并且可以将语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式。  

二、demo:

1、加减法计算器:

//抽象表达式
public interface AbstractExpression {int interprete(HashMap<String, Integer> var);
}//终结符表达式
public class VarExpression  implements AbstractExpression {private String key;public VarExpression(String key) {this.key = key;}public int interprete(HashMap<String, Integer> var) {return (Integer) var.get(this.key);}
}//加法符号  非终结表达式
public class AddExpression implements AbstractExpression{private AbstractExpression left;private AbstractExpression right;public AddExpression(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}// 把左右两个表达式运算的结果加起来public int interprete(HashMap<String, Integer> var) {return this.left.interprete(var) + this.right.interprete(var);}
}//减法符号  非终结表达式
public class SubExpression implements AbstractExpression{private AbstractExpression left;private AbstractExpression right;public SubExpression(AbstractExpression left, AbstractExpression right) {this.left = left;this.right = right;}// 把左右两个表达式运算的结果加起来public int interprete(HashMap<String, Integer> var) {return this.left.interprete(var) - this.right.interprete(var);}
}
//封装计算器类
public class Calculator {private AbstractExpression expression;public Calculator(String expStr) {// 定义一个堆栈,安排运算的先后顺序Stack<AbstractExpression> stack = new Stack<AbstractExpression>();// 表达式拆分为字符数组char[] charArray = expStr.toCharArray();// 运算AbstractExpression left = null;AbstractExpression right = null;for (int i = 0; i < charArray.length; i++) {switch (charArray[i]) {case '+':left = stack.pop();right = new VarExpression(String.valueOf(charArray[++i]));stack.push(new AddExpression(left, right));break;case '-':left = stack.pop();right = new VarExpression(String.valueOf(charArray[++i]));stack.push(new SubExpression(left, right));break;default: // 公式中的变量stack.push(new VarExpression(String.valueOf(charArray[i])));}}// 把运算结果抛出来this.expression = stack.pop();}// 计算结果public int calculate(HashMap<String, Integer> var) {return this.expression.interprete(var);}
}//客户端
public static void main(String args[]){// 构造运算元素的值列表HashMap<String, Integer> ctx = new HashMap<String, Integer>();ctx.put("a", 10);ctx.put("b", 20);ctx.put("c", 30);ctx.put("d", 40);ctx.put("e", 50);ctx.put("f", 60);Calculator calc = new Calculator("a+b-c");int result = calc.calculate(ctx);System.out.println("Result of a+b-c: " + result);calc = new Calculator("d-a-b+c");result = calc.calculate(ctx);System.out.println("Result of d-a-b+c: " + result);}输出:
Result of a+b-c: 0
Result of d-a-b+c: 40

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

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

相关文章

Nginx搭配负载均衡和动静分离:构建高性能Web应用的完美组合

目录 前言 一、Nginx简介 1.Nginx是什么 2.Nginx的特点 3.Nginx在哪使用 4.如何使用Nginx 5.Nginx的优缺点 6.Nginx的应用场景 二、负载均衡和动静分离 1.负载均衡 2.动静分离 三、Nginx搭载负载均衡并提供前后端分离后台接口数据 1.Nginx安装 2.tomcat负载均衡 …

如何利用AppScan扫描H5页面,进行安全测试?

前期项目组接触的都是Web安全测试&#xff0c;今天做安全测试的时候&#xff0c;有一个项目刚好有H5页面&#xff0c;用以前那种AppScan内置浏览器的探索方式是不行的&#xff0c;研究了下&#xff0c;可以使用外部设备进行探索。 AppScan有两种手动探索方式&#xff0c;一种是…

【实战Flask API项目指南】之五 RESTful API设计

实战Flask API项目指南之 RESTful API设计 本系列文章将带你深入探索实战Flask API项目指南&#xff0c;通过跟随小菜的学习之旅&#xff0c;你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧&#xff01; 前言 当小菜踏入Flask后端开发的世界时…

(免费领源码)java#ssm#mysql宠物网站系统07183-计算机毕业设计项目选题推荐

摘 要 在信息飞速发展的今天&#xff0c;网络已成为人们重要的信息交流平台。宠物网站每天都有大量的信息需要通过网络发布&#xff0c;为此&#xff0c;本人开发了一个基于B/S&#xff08;浏览器/服务器&#xff09;模式的宠物网站系统。 该系统以JJava编程语言、MySQL和SSM框…

【软考中级】软件设计师-下午题

下午题 试题一 黑洞&#xff1a;加工有输入无输出 白洞(奇迹)&#xff1a;加工有输出无输入 灰洞&#xff1a;数据流输入的加工不足以产生输出 结构化语言&#xff1a; IF *** THEN ELSE IF *** THEN ******* END IF END IF 数据流的父子图平衡&#xff0c;如果父子图平衡就不…

一文深入了解 CPU 的型号、代际架构与微架构

在 10 月 16 号的时候&#xff0c;Intel 正式发布了第 14 代的酷睿处理器。但还有很多同学看不懂这种发布会上发布的各种 CPU 参数。借着这个时机&#xff0c;给大家深入地讲讲 CPU 的型号规则、代际架构与微架构方面的知识。 CPU 在整个计算机硬件中、技术体系中都算是最最重…

Scala和Play WS库编写的爬虫程序

使用Scala和Play WS库编写的爬虫程序&#xff0c;该程序将爬取网页内容&#xff1a; import play.api.libs.ws._ import scala.concurrent.ExecutionContext.Implicits.global ​ object BaiduCrawler {def main(args: Array[String]): Unit {val url ""val proxy…

ChinaSoft 论坛巡礼 | 安全攸关软件的智能化开发方法论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

全功能测试框架 - Carina

Carina是一个基于Java的测试自动化框架&#xff0c;它将所有测试层结合在一起&#xff1a;移动应用程序&#xff08;web、本机、混合&#xff09;、web应用程序、REST服务和数据库。 github&#xff1a;GitHub - zebrunner/carina: Carina automation framework (TestNG): Web…

OpenGL_Learn05(纹理)

1. 纹理贴图 wall.jpg (512512) (learnopengl-cn.github.io) 纹理过滤分为&#xff1a;邻近和线性&#xff0c;这跟opencv图像处理一样。 多级渐远纹理 四种采样方式&#xff1a; 代码实现&#xff1a; std_image.h https://github.com/nothings/stb/blob/master/stb_image.…

体验SOLIDWORKS旋转反侧切除增强 硕迪科技

大家在设计中经常使用的旋转切除命令在solidworks2024版本中迎来了新的增强&#xff0c;添加了旋转反侧切除选项。在设计过程中不必修改复杂的草图即可切除掉我们不需要的部分。使设计工作更加方便快捷。 打开零部件后&#xff0c;点击键盘上的S键并输入旋转切除以搜索该命令&a…

uni-app---- 点击按钮拨打电话功能点击按钮调用高德地图进行导航的功能【安卓app端】

uniapp---- 点击按钮拨打电话功能&&点击按钮调用高德地图进行导航的功能【安卓app端】 先上效果图&#xff1a; 1. 在封装方法的文件夹下新建一个js文件&#xff0c;然后把这些功能进行封装 // 点击按钮拨打电话 export function getActionSheet(phone) {uni.showAct…

Python最强自动化神器Playwright!再也不用为爬虫逆向担忧了!

版权说明:本文禁止抄袭、转载,侵权必究! 目录 一、简介+使用场景二、环境部署(准备)三、代码生成器(优势)四、元素定位器(核心)五、追踪查看器(辅助)六、权限控制与认证(高级)七、其他重要功能(进阶)八、作者Info一、简介+使用场景 Playwright是什么?来自Chat…

intellij idea拉取最新的依赖包

intellij idea setting 拉取最新的依赖包 File --> Settings --> Build, Execution, Deployment --> Build Tools --> Maven --> 勾选 Always update snapshots. 一般情况下&#xff0c;设置完就可以拉取到最新的依赖包了。 如下&#xff1a; 安装最新的依赖…

浅析运维平台在实现光伏发电数据监控的应用

安科瑞 崔丽洁 摘要&#xff1a;全球化经济社会的快速发展&#xff0c;加快了传统能源的消耗&#xff0c;导致能源日益短缺&#xff0c;与此同时还带来了严重的环境污染。因此&#xff0c;利用没有环境污染的太阳能进行光伏发电获得了社会的普遍关注。本文根据传统式光伏电站行…

Java随机获取某个范围内的随机整数

随机获取某个范围内的随机整数 一、代码 /*** 随机获取某个范围内的随机整数的值* param min 最小值* param max 最大值* return*/public static int randomNum(int min,int max) {// 创建一个Random对象Random random new Random();// 生成指定范围内的随机整数int randomI…

day02_第一个Java程序

在开发第一个Java程序之前&#xff0c;我们必须对计算机的一些基础知识进行了解。 常用DOS命令 Java语言的初学者&#xff0c;学习一些DOS命令&#xff0c;会非常有帮助。DOS是一个早期的操作系统&#xff0c;现在已经被Windows系统取代&#xff0c;对于我们开发人员&#xf…

zabbix6.4监控centos

1、关闭防火墙 setenforce 0 #关闭SELinux sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config #设置永久关闭SELinux systemctl stop firewalld.service #关闭防火墙 systemctl disable firewalld.service …

OPCUA 行业配套标准:机器人

OPC UA 定义了对象&#xff0c;对象类型&#xff0c;结构化组织能力和定义对象之间关系的能力&#xff0c;利用这些基础和衍生类型及对象&#xff0c;用户还可以搭建出更复杂的类型&#xff0c;关系和对象。 如果不同的厂商或者用户定义的信息模型不同&#xff0c;将会影响系统…

【蓝桥杯省赛真题41】Scratch电脑开关机 蓝桥杯少儿编程scratch图形化编程 蓝桥杯省赛真题讲解

目录 scratch电脑开关机 一、题目要求 编程实现 二、案例分析 1、角色分析