行为型——解释器模式(Interpreter)day20

STM32串口调试踩坑记:HAL_UART_ErrorCallback里不先解锁,你的中断接收就废了 本文深入分析了STM32串口调试中HAL_UART_ErrorCallback的锁机制陷阱,指出在错误回调中不先解锁会导致中断接收失效的问题。通过解析HAL库源码,提出了正确的错误处理实现方法,并分享了预防措施与最佳实践,帮助开发者提升串口通信的可靠性。 阅读详情

解释器模式基本介绍

基本介绍

  1. 在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器
  2. 解释器模式( Interpreter Pattern) :是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
  3. 应用场景
    -应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
    -些重复出现的问题可以用一种简单的语言来表达
    -一个简单语法需要解释的场景
  4. 这样的例子还有, 比如编译器、运算表达式计算、正则表达式、机器人等

解释器模式的类图

在这里插入图片描述
➢对原理类图的说明-即(解释器模式的角色及职责)

  1. Context:是环境角色,含有解释器之外的全局信息.
  2. AbstractExpression: 抽象表达式,声明一 个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享
  3. TerminalExpression: 为终结符表达式,实现与文法中的终结符相关的解释操作
  4. NonTermialExpression: 为非终结符表达式,为文法中的非终结符实现解释操作.
  5. 说明: 输入Context he TerminalExpression 信息通过Client 输入即可

解释器模式来实现四则

  1. 应用实例要求.
    通过解释器模式来实现四则运算,
    如计算a+b-c的值
  2. 类图
    在这里插入图片描述
package com.xhl.Interpreter;

import java.util.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);
}

package com.xhl.Interpreter;

import java.util.HashMap;

public class VarExpression extends Expression{

	private String key;//key = a;
	
	public VarExpression(String key) {
		this.key = key;
	}
	
	
	@Override
	public int interpreter(HashMap<String, Integer> var) {
		// TODO Auto-generated method stub
		return var.get(this.key);
	}

}
package com.xhl.Interpreter;

import java.util.HashMap;

public class SymbolExpression extends Expression{

	protected Expression left;
	protected Expression right;
	
	public SymbolExpression(Expression left, Expression right) {
		super();
		this.left = left;
		this.right = right;
	}
	
	//因为SymbolExpression是让其子类来实现,因此interpreter 是一个默认实现
	@Override
	public int interpreter(HashMap<String, Integer> var) {
		// TODO Auto-generated method stub
		return 0;
	}

}

package com.xhl.Interpreter;

import java.util.HashMap;

public class SubExpression extends SymbolExpression{

	public SubExpression(Expression left, Expression right) {
		super(left, right);
		// TODO Auto-generated constructor stub
	}
	
	public int interpreter(HashMap<String, Integer> var) {
		return super.left.interpreter(var)-super.right.interpreter(var);
	}

}

package com.xhl.Interpreter;

import java.util.HashMap;

public class AddExpression extends SymbolExpression{

	public AddExpression(Expression left, Expression right) {
		super(left, right);
		// TODO Auto-generated constructor stub
	}
	
	public int interpreter(HashMap<String, Integer> var) {
		return super.left.interpreter(var)+super.right.interpreter(var);
	}

}

package com.xhl.Interpreter;

import java.util.HashMap;
import java.util.Stack;

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();//取出a
				right = new VarExpression(String.valueOf(charArray[++i]));//取出b
				stack.push(new AddExpression(left, right));
				break;
			case '-':
				left = stack.pop();//取出a
				right = new VarExpression(String.valueOf(charArray[++i]));//取出b
				stack.push(new SubExpression(left, right));
				break;
			default:
				stack.push(new VarExpression(String.valueOf(charArray[i])));
				break;
			}
		}
		
		this.expression = stack.pop();
	}
	
	public int run(HashMap<String, Integer> var) {
		return this.expression.interpreter(var);
	}
}

package com.xhl.Interpreter;

import java.io.BufferedReader;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class InterpreterDemo {
	public static void main(String[] args) throws IOException{
		String expStr = getExpStr();
		HashMap<String, Integer> var = getValue(expStr);
		Calculator calculator = new Calculator(expStr);
		System.out.println("运算结果:"+expStr+"="+calculator.run(var));
	}
	
	public static String getExpStr() throws IOException{
		System.out.println("请输入表达式");
		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 c : expStr.toCharArray()) {
			if(c!='+'&&c!='-') {
				if(!map.containsKey(String.valueOf(c))) {
					System.out.println("请输入"+c+"的值");
					String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
					map.put(String.valueOf(c), Integer.valueOf(in));
				}
			}
		}
		return map;
	}
}

在这里插入图片描述

总结

  1. 当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性
  2. 应用场景: 编译器、运算表达式计算、正则表达式、机器人等
  3. 使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低.
【DRAM存储器六十七】DDR5介绍--训练相关之write leveling 详述DDR5 write leveling细节 阅读详情

相关推荐

从零开始写一个RTSP服务器(一)RTSP协议讲解

从零开始写一个RTSP服务器系列 从零开始写一个RTSP服务器(一)不一样的RTSP协议讲解 从零开始写一个RTSP服务器(二)RTP传输H.264(待写) 从零开始写一个RTSP服务器(三)一个传输H.264的RTSP服务器(待写) 从零开始写一个RTSP服务器(四)RTP传输AAC(待写) 从零开始写一个RTSP服务器(五)一个传输AAC的RTSP服务器(待写) 从零开始写一个RTSP服务器(...

JT同学的博客 7万+

【Interpreter】构建简单的解释器(第4部分)

文章目录【Interpreter】构建简单的解释器(第4部分) 【Interpreter】构建简单的解释器(第4部分) 简单翻译了下,方便查看,水平有限,喜欢的朋友去看 原文! 你被动地学习这些文章,还是你积极地参与练习? 我希望你一直在积极地练习。 我真的会很高兴:) 还记得孔子说过的话吗?(译注:这好像出自《荀子·儒效》

问题不大 3899

spring-ai学习(四)-MCP

创建一个springai项目1.依赖。

zql1455890112的博客 1384

【Java教程】Day20-15 设计模式:行为型模式——解释器模式(Interpreter Pattern)

解释器模式(Interpreter Pattern)是一种行为型设计模式,用于定义语言的文法表示,并设计一个解释器来解析和执行该语言中的句子。它是一种特定场景下的解决方案,常用于需要解析和解释用户输入的复杂规则或语言的场合。

max202011161630的博客 643

机器学习第五章之决策树模型

机器学习专题系列

wangyutao12345的博客 5182

【校招】SHL 的 General Ability (GA, 通用能力测试)

SHL 的 General Ability (GA, 通用能力测试) 文章目录SHL 的 General Ability (GA, 通用能力测试)1、归纳推理题1.1 圈圈线条推理1.2 图形颜色位置推理1.3 箭头指向推理2. 数字推理题攻略3. 语言推理题 1、归纳推理题   归纳推理题我把它总结为三种类型:圈圈线条推理;图形颜色位置推理;箭头指向推理。 1.1 圈圈线条推理   你别看这个题目看起来很复杂,其实很简单,而且这个题型的题目背后原理都一样!我把我的 tips 偷偷分享给你们嘿嘿~先从 A

Sunnyside_ 2万+

设计模式精讲 Day 15:解释器模式(Interpreter Pattern)

解释器模式是一种行为型设计模式,用于定义一个语言的文法,并为该语言中的每个句子构建一个抽象语法树(Abstract Syntax Tree, AST),然后使用该语法树来解释和执行这些句子。核心思想:将语言的语法表示为对象,使得可以动态地解释语言中的表达式。@Override@Override@Override本篇文章详细讲解了解释器模式的核心思想、实现方式、适用场景及实际案例。

在未来等你的专栏 1107

HDLbits练习11 - Counter 1-12 ( Exam/ece241 2014 q7a )

(如这题用于当复位信号为高或者计数器递增至12时,该信号置1使计数器的输入信号 ’ d ’ 变为 ’ 4’b0001 ’ ,再加载到 ’ Q ’ 中。当 ’ load ’ 信号为高时,在时钟的上升沿,计数器会将 ’ d ’ 输入的值加载到 ’ Q ’ (计数器的输出)中,而不是递增当前值。用途:在时钟上升沿触发的情况下,如果 ’ enable ’ 信号为高,计数器的值会递增,如果 ’ load ’ 信号为高,计数器将加载 ’ d ’ 信号的值。作用: ’ Q ’ 是计数器的当前值,也是模块的主要输出。

weixin_62830176的博客 472

设计模式21——Interpreter设计模式

Interpreter解释器设计模式的定义:给定一个语言,定义其文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 Interpreter解释器设计模式角色如下: (1).抽象表达式(AbstractExpression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要定义一个interpret()方法,称做解释操作。  (2).终结符表达式(Te

Tony Chen的专栏 1853

DDR5 输入时钟抖动规范全解析!技术宅必看

简单说,时钟抖动就是时钟信号边沿的“颤抖”——信号本来应该在某个固定时间跳变,但实际时刻可能会前后波动。这种波动可能是随机的,也可能是确定性的。随机抖动(Random Jitter, Rj):符合高斯分布,像是你家猫咪不经意的晃动。确定性抖动(Deterministic Jitter, Dj):受限于特定周期或模式,像是邻居装修时的规律敲击声。⚠️ 注意,如果时钟抖动超出规格,DDR5可能无法正确接收或发送数据,内存错误、系统崩溃可就跟着来了!

weixin_43199439的博客 390

SAP ABAP Web Service 的创建与消费:保姆级教程

SOAP 定义了消息的格式和传输规则,使得 Web Service 可以在不同的操作系统和网络环境中通信。通过 WSDL,服务的提供者可以明确地定义服务的功能,而服务的使用者则可以通过解析 WSDL 文件,了解如何正确地调用该服务。它封装了与 Web 服务通信的所有复杂性,如消息格式的构建、传输协议的选择、请求的发送和响应的处理等。除了本文介绍的 ABAP 编程语言之外,我们还可以通过 Java,Node.js,C++,C#,Python 等其他编程语言来消费本文创建的 ABAP Web Service.

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 713

设计模式(21)-解释器模式

思想:当 有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,定义一个解释器,这 个解释器使用该表示来解释语言中的句子。 场景:其 实,从物理结构上,该模式的代码架构看起来可能和Composite模式一模一样,致使其针对的逻 辑语义不同。Composite模式描述一种一般的整体和部分使用接口上的一致性,而Interpreter模 式则侧重于语言解释器的实现构架。 实现:如

wzq6578702的专栏 328

融合双主干网络提升YOLOv8性能一种基于SOTA思想的目标检测改进

YOLOv8采用了单一的主干网络进行特征提取,通常是基于CSPDarknet作为骨干网络,在目标检测过程中通过不同的卷积层提取不同尺度的信息。虽然这种设计在大多数应用场景下表现出色,但在面对复杂背景、细节丰富的物体或小物体检测时,YOLOv8有时难以保持良好的精度。在本文中,我们提出了一种基于双主干网络的YOLOv8改进方案,通过结合先进的SOTA思想,全面提升了YOLOv8在目标检测任务中的表现。双主干网络架构。

博客 1153

23个设计模式一文搞懂

本笔记涵盖 23 种经典设计模式,按创建型、结构型、行为型三大类整理。每个模式配有生活类比、核心思想、结构图解、实现要点、真实应用案例、适用场景、优缺点分析及常见面试题。

weixin_72753562的博客 802

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

uwsgi 启动时排错记录

启动uwsgi:sudo uwsgi --ini uwsgi,ini #uwsgi.ini为启动文件 查看uwsgi是否启动成功:ps aux | grep uwsgi 发现没有启动成功 去uwsgi.log(在uwsgi.ini同级目录下)排错日志中找原因,发现报错如下 chdir() to /home/ubuntu/day01 #项目目录 chdir(): No such file o...

yutaixin的博客 5400

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

创建型——工厂系列(Factory)day04

任何可以产生对象的方法或类,都可以称为工厂 单例也是一种工厂 为什么有了new以后,还要有工厂? 1、灵活控制生产过程 2、权限、修饰、日志…… 接口模式 package cn.xhl.interfacemodel; public interface IFruit { public void plant(); public void harvest(); public void grow(); } package cn.xhl.interfacemodel; public class ..

zero_ko的博客 2502

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

创建型——建造者(Builder)day06

分离复杂对象的构建和表示 同样的构建过程可以创建不同的表示 建造者模式和模板方法模式非常像 建造者模式强调构造对象 模板方法模式强调方法执行 基本介绍 1、建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。 2、建造者模式是一步一步创建一个复 杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。 建造者的四个角色 1、.

zero_ko的博客 2420

结构型——外观模式(Facade)&&行为型——中介者模式(Mediator)day11

结构型——外观模式(Facade) 外观模式基本介绍 外观模式(Facade),外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节 一个简单的例子理解:去一些政府部门办事,会跑很多不同的部门,可能去了部门A,部门A又让你去部门B……这样就很麻烦 如果使用门面模式,用户只需要访问门面,由门面模式去协调内部的关系。 外观模式

zero_ko的博客 442

行为型——命令模式(Command) day15

目录命令模式基本介绍命令模式的原理类图实例——智能生活项目需求命令模式的总结 命令模式基本介绍 命令模式(Command Pattern) :在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计 命名模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。 在命名模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命名),同

zero_ko的博客 330

设计模式七大原则day01

设计模式七大原则 单一职责原则: 单一职责原则(Single Responsibility Principle, SRP)的定义是:指一个类或者模块应该有且只有一个改变的原因。如果一个类承担的职责过多,就等于把这些职责耦合在一起了。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当发生变化时,设计会遭受到意想不到的破坏。而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。此原则的核心就是解耦和增强内聚性。 含义:对于一个类,只有一个引起该类变化的原因;该类的职责是

zero_ko的博客 317

行为型——模板方法模式(Template)day14

模板方法模式基本介绍 模板方法模式 (Template Method Pattern),又叫模板模式(Template Pattern), 指 在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。 简单说, 模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤 这种类型的设计模式属于行为型模式。 模板方法模式原理类图 ➢对原理类图的说明-即(模板方法模式的角色及职责)

zero_ko的博客 313

结构型——适配器模式(Adapter)day07

基本介绍 适配器模式(Adapter Pattemn)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。 其别名为包装器(Wrapper) 适配器模式属于结构型模式 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式 工作原理 适配器模式:将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容 从用户的角度看不到被适配者,是解耦的 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法 用户收到反馈结果

zero_ko的博客 272

结构型——桥接模式(Bridge)day08

桥接模式基本介绍 桥接模式(Bridge模式)是指:将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。 是一种结构型设计模式 Bridge模式基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展 桥接模式原理图 说明: Client类:桥接模式的调用者 抽象类(Abstraction) :维护了Implementor/

zero_ko的博客 269

行为型——策略模式(Strategy)day22

策略模式基本介绍 策略模式(Strategy Patterm) 中,定义算法族(策略组),分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户 这算法体现了几个设计原则,第一、把变化的代码从不变的代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口) ;第三、多用组合/聚合,少用继承(客户通过组合方式使用策略) . 策略模式的原理类图 说明:从上图可以看到,客户context有成员变量strategy或者其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定

zero_ko的博客 248

行为型——职责链模式(Responsibility)day23

职责链模式基本介绍 职责链模式( Chain of Responsibility Pattern),又叫责任链模式,为请求创建了一个接收者对象的链。这种模式对请求的发送者和接收者进行解耦。 职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。 这种类型的设计模式属于行为型模式 职责链模式类图 ➢对原理类图的说明-即(职责链模式的角色及职责) Handler: 抽象的处理者,定义了一个处理请求的接口,同时含义另外Handler

zero_ko的博客 229

行为型——备忘录模式(Memento)day19

文章目录备忘录模式基本介绍备忘录模式的原理类图代码实现备忘录模式总结 备忘录模式基本介绍 备忘录模式(Memento Pattern) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态 可以这里理解备忘录模式:现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同意见的事情,以防忘记了。而在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对 象的某;种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原

zero_ko的博客 226
上一篇: 行为型——备忘录模式(Memento)day19
下一篇: 行为型——状态模式(State)day21
哆唻咪à
博客等级 码龄9年 0粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值