设计模式-20解释器模式

语音测试(二)音频标注(praat) 通过点击红线下方的圆点进行区域划分,在区域中标注所属的类别。按住Alt+Backspace 键取消蓝色线条。 阅读详情

解释器模式

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

在这里插入图片描述

角色说明:
  • Context:是环境角色,含有解释器之外的全局信息
  • AbstractExpression:抽象表达式,声明一个抽象的解释操作,这个方法为抽象语法树中所有节点所共享
  • TerminalExpression:为终结符表达式,实现了与文法中的终结符相关的解释操作
  • NonTerminalExpression:为非终结表达式,为文法中的非终结符实现解释操作
  • 说明:输入Context和TerminalExpression信息通过client输入即可
案例:

通过解释器模式实现:一个计算a+b-c表达式的值

/**
 * 抽象解释器表达式类
 */
public abstract class Expression {

    //解释公式和数值,key就是公式(表达式)参数[a,b,c],如:a + b - c
    //value就是具体值
    protected abstract int interpreter(HashMap<String,Integer> var);
}

/**
 * 变量解释器
 */
public class VarExpression extends Expression {
    private String key;//key =a,key=b

    public VarExpression(String key) {
        this.key = key;
    }
    //var 就是{a=10,b=20}
    //根据变量名称返回对应的值
    @Override
    protected int interpreter(HashMap<String, Integer> var) {
        return var.get(this.key);
    }
}

/**
 * 抽象符号解释器,这里每个运算符号,都只和自己左右两个数字有关系
 * 但左右两个数字有可能也是一个解析的结果,无论何种类型,都是Expression的实现类
 */
public abstract class SymbolExpression extends Expression{

    protected Expression left;
    protected Expression right;

    public SymbolExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

}

public class AddSymbolExpression extends SymbolExpression {

    public AddSymbolExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    protected int interpreter(HashMap<String, Integer> var) {
        return super.left.interpreter(var) + super.right.interpreter(var);
    }
}

public class SubSymbolExpression extends SymbolExpression {

    public SubSymbolExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    protected int interpreter(HashMap<String, Integer> var) {
        return super.left.interpreter(var) - super.right.interpreter(var);
    }
}

public class Calculator {

    private Expression expression;

    public Calculator(String expStr) {
        Stack<Expression> stack = new Stack<>();
        char[] charArray = expStr.toCharArray();

        Expression left;
        Expression right;
        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 AddSymbolExpression(left,right));
                    break;
                case '-':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubSymbolExpression(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);
    }

}


public class Client {

    public static void main(String[] args) throws Exception {
        String expStr = getExprStr();
        HashMap<String, Integer> var = getValue(expStr);
        Calculator calculator = new Calculator(expStr);

        System.out.println("运算结果:" + expStr + " = " + calculator.run(var));
    }

    private static String getExprStr() throws Exception {
        System.out.print("请输入表达式:");
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }

    private static HashMap<String, Integer> getValue(String exprStr) throws Exception {
        HashMap<String, Integer> map = new HashMap<>();
        for (char ch : exprStr.toCharArray()) {
            if (ch != '+' && ch != '-') {
                if (!map.containsKey(String.valueOf(ch))) {
                    map.put(String.valueOf(ch), Integer.parseInt(getVar(String.valueOf(ch))));
                }
            }
        }
        return map;
    }

    private static String getVar(String var) throws Exception {
        System.out.print("请输入" + var + "的值:");
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }

}
解释器模式注意事项和细节:
  • 当有一个语言需要解释执行,可将改语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有很好的扩展性
  • 使用解释器模式可能带来的问题:解释器模式会也引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低
  • 谨慎使用,解释器模式用于处理较难的问题
【android bluetooth 案例分析 01】【HiCar 详解 3】【hicar时如何交换Wifi参数的】 如果直接使用 L2CAP(不经过 RFCOMM),会需要额外的协议来保证可靠性,而 RFCOMM 天然支持。BLE 广播的数据长度受限(31 字节 / 255 字节扩展),不适合传输复杂的 Wi-Fi 连接参数。使用 RFCOMM 传输参数,可以兼容不同厂商的车机和手机,而无需依赖特殊的蓝牙功能。手机解析这些参数,并使用 Wi-Fi Direct 连接到车机。,然后才能让 Wi-Fi Direct 进行真正的数据传输。,适合传输 Wi-Fi 连接参数等关键数据。,可以安全地交换 Wi-Fi 连接信息。 阅读详情

相关推荐

NX/UG二次开发—CAM—设置程序修剪边界Boundary

最近做了一个设置CAM程序边界的小工具,分享一下经验(官方的代码在文章末尾处),以下均以修剪边界曲线为例。 以下为官方提供的源码: /***************************** Include Files **********************************/ #include <stdlib.h> #include <uf.h> #include <uf_obj.h> #include <uf_object_type

门前大桥下,游过一群鸭,快来看一看,原来是C++ 3732

编译原理抽象语法树生成及执行实例

打印1+1结果搞得这么复杂并非炫技,只是用于简单展示:1、词法分析器;2、语法分析器;3、脚本编译器;4、编译执行器,四个过程,因为他们是实现自定义脚本引擎的基础。

bossfriday - 个人博客 2403

【v4l2】在Android SDK中交叉编译v4l2-ctl

为调试Android设备中camera的相关功能,需要引入v4l2-ctl工具。由于厂商提供的Android SDK源码中未集成v4l2-utils(包含v4l2-ctl以及其它组件的工具包),故需要下载v4l2-utils源码,并在Android SDK中交叉编译生成v4l2-ctl可执行文件。本文讲述其过程步骤。

rentong123的博客 1322

AST(抽象语法树)超详细

自己研究的东西会用到AST,就自己通过查阅资料,整理一下。 本文目录 第一部分:AST的作用 第二部分:AST的流程 第三部分: Eclipse AST的获取与访问 第一部分:AST的作用 首先来一个比较形象的,转载自:AST-抽象语法树,讲述了为什么需要讲源代码转化为AST,总结就是:AST不依赖于具体的文法,不依赖于语言的细节,我们将源代码转化为AST后,可以对AST做很多的操作,...

Yi Sun的博客 17万+

微信小程序如何转云开发

小程序转云开发

zhangxiaobai___的博客 3913

从0死磕全栈之使用 VS Code 调试 Next.js 应用完整指南

调试目标推荐方式客户端组件VS Code + Chrome 调试器(pwa-chrome中间件(Middleware)同服务端方式静态生成(SSG)逻辑需在next build时调试,建议改用dynamic路由临时测试通过合理配置 VS Code 调试器,你可以像调试普通 Node.js 或前端项目一样,高效排查 Next.js 应用中的各类问题。🐞。

weixin_44058951的博客 1158

详解AST抽象语法树

浅谈 AST 先来看一下把一个简单的函数转换成AST之后的样子。 // 简单函数 function square(n) { return n * n; } // 转换后的AST { type: "FunctionDeclaration", id: { type: "Identifier", name: "square" }, pa...

huangpb的博客 5万+

【ArcGIS遇上Python】ArcGIS10.8 Python代码批量完美实现MODIS NDVI数据格式转换和投影变换

由于论文的需要,将MODIS NDVI数据进行投影变换和格式转换,具体操作可以参照:《ArcGIS10.8完美实现MODIS NDVI数据格式转换和投影变换》,但是该文章中的做法只能一次性实现一景影像的转换,没法批量,虽然ArcGIS中提供了Batch的方法但是需要挨个添加数据,确定输出路径等等,本文就实现以ArcGIS10.8 Python代码批量完美实现MODIS NDVI数据格式转换和投影变换。先来看投影后的效果: 在实现批量投影转换之前,需要两个投影文件:Sinusoidal.prj和MyAl

智慧空间实验室 3814

正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——2 构造抽象语法树

简要介绍     构造抽象语法树是构造基于DFA的正则表达式引擎的第一步。目前在我实现的这个正则表达式的雏形中,正则表达式的运算符有3种,表示选择的|运算符,表示星号运算的*运算符,表示连接的运算符cat(在实际正则表达式中被省去)。 例如对于正则表达式a*b|c,在a*和b之间省略了连接运算符cat。其中|、cat运算符是双目运算符,*运算符是单目运算符。 下图来自编译原理一书:

超然于物外 烟火于一瞬 6059

基于STM32、HAL库的ATMXT1066TD触摸屏控制器驱动程序设计

0x11) // 0x11是ATMXT1066的家族ID。// 最多支持10点触摸。// 足够存储10点触摸数据。

corlin6688的博客 164

1、vectorCast单元测试常用操作

进入软件主页面,点击file,选择set working directory,随便选择一个保存该项目的目录即可。

weixin_59334478的博客 2155

如何让孩子爱上设计模式 ——20.解释器模式(Interpreter Pattern)

如何让孩子爱上设计模式 ——20.解释器模式(Interpreter Pattern)标签: 设计模式初涉描述性文字解释器模式是一个用的比较少的设计模式,而且不太好理解,先说下概念相关的东西 再写个代码示例帮助下理解:定义给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个 解释器,客户端可以使用这个解释器来解释这个语言中的句子。四个角色 AbstractExpression:

Coder-Pig的猪栏 18万+

UNet改进(6):基于注意力机制的多尺度医学图像分割方法

本文提出了一种集成多尺度注意力机制的UNet改进模型UNetWithAttention,用于提升医学图像分割性能。该模型在标准UNet架构基础上,设计了并行3×3、5×5、7×7卷积核的多尺度注意力模块,通过特征拼接和Sigmoid激活生成注意力权重,实现了对不同尺寸病变的自适应关注。模型采用分离式设计,将特征提取与特征选择解耦,在编码器-解码器各阶段嵌入注意力模块。实验表明,该方法在视网膜血管分割和肺结节检测任务中优于标准UNet,Dice系数和IOU分别提升2.6%和4.1%,同时保持计算效率。

2501_91516851的博客 1324

设计模式笔记20:解释器模式(Interpreter Pattern)

一、解释器模式的内容 解释器模式(Interpreter Pattern) :定义语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”意思是使用规定格式和语法的代码,它是一种类行为型模式。 如果在系统中某一特定类型的问题发生的频率很高,此时可以考虑将这些问题的实例表述为一个语言中的句子,因此可以构建一个解释器,该解释器通过解释这些句子来解决这些问题。解释器模式描述了如

Snowball 1748

老版QQ原生表情gif动态

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

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

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

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

max202011161630的博客 643

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

.NET设计模式(20):解释器模式(Interpreter Pattern)

动机(Motivate):    在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。    在这种情况下,将特定领域的问题表达为某种文法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。意图(Intent):    给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言

微软新技术 723

精读C++20设计模式——行为型设计模式:解释器模式

摘要: 本文介绍了C++20中的解释器模式(Interpreter Pattern),这是一种将语言语法规则和执行逻辑以面向对象方式实现的行为型设计模式。文章首先通过简单的整数解析示例展示基本概念,然后逐步扩展为支持加减乘除和括号的完整表达式求值器。解释器模式通过将语法元素映射为类,每个类负责解释特定语法片段,适用于实现小型领域特定语言(DSL)。作者指出,虽然Python等解释型语言本身使用此模式,但实际开发中更常见于需要自定义DSL的场景。文章提供了清晰的代码示例,展示了从基础到进阶的解释器实现过程。

charlie114514191的博客 837

【python设计模式】20、解释器模式

该模式中,解释器通过将表达式转换为可以执行的对象来实现对表达式的解释和执行。解释器模式将问题的解决方案表示为语法树中的表达式。解释器也有类似的工作原理,但是它们执行的任务不是将代码编译成可执行文件,而是将某种特定语言的表达式转换为可执行的对象。下面是一个简单的例子,其中我们定义了一个简单的语言,该语言只包含两个命令:"add" 和 "subtract",并且只接受两个参数。总的来说,解释器模式是一种实现自定义语言解释器的有效方法,它可以提高代码的可维护性和可扩展性,同时还可以使程序更具可读性和可理解性。

Htojk的博客 666

漫谈设计模式 [20]:解释器模式

老鸟:解释器模式是一种设计模式,用于定义一种语言的语法表示,并提供一个解释器来解释这些表示。简单来说,它可以帮助我们解析和执行特定语言的语法规则。菜鸟:听起来很高深,有没有简单一点的例子?老鸟:当然有。想象一下,我们有一个简单的算术表达式,比如 “3 + 5”。我们需要一个程序来解析这个表达式并计算其结果。解释器模式就可以帮我们实现这个任务。老鸟:今天我们讨论了解释器模式的基本概念、实现方式及其优势和适用场景。你觉得如何?菜鸟:非常有趣!我对解释器模式有了初步的了解。你能推荐一些延伸阅读的资源吗?老鸟。

刘炫320的博客 1516

二、20【设计模式】之解释器模式

今天的博客主题 设计模式——》设计模式之解释器模式 解释器模式 IP (Interpreter Pattern) 定义 给定一门语言,定义它的一种文法表示,并定义一个解释器,用来解释语言中的句子。 这种模式一般被用在SQL的解析,符号的处理等。 解释器模式也是一种使用频率低学习难度较大的一个设计模式。 应用场景 1)一些重复出现的问题可以用一种简单的语言来进行表达。 2)一个简单语法需要解释的场景。 3)编译器,运算表达式的计算 4) 优点 ...

刘总Java 1879

设计模式——20. 解释器模式

解释器模式(Interpreter Pattern)是一种行为型设计模式,它用于定义一门语言的语法解析,并为该语言创建解释器。该模式将一个问题或领域表达成一个语言,然后提供一个解释器来解释这种语言中的表达式,以执行特定操作。

442

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

**定义:**给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。 **类型:**行为类模式 类图: ​ 解释器模式是一个比较少用的模式,本人之前也没有用过这个模式。下面我们就来一起看一下解释器模式。 解释器模式的结构 抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操...

cowbin2012的专栏 1万+

设计模式(20)——解释器模式

目录四则运算问题传统方法解决四则运算问题分析解释器模式解释器模式来实现四则解释器模式在Spring框架应用的源码剖析解释器模式的注意事项和细节 四则运算问题 通过解释器模式来实现四则运算,如计算a+b-c的值,具体要求 先输入表达式的形式,比如a+b+c-d+e,要求表达式的字母不能重复 在分别输入a,b,c,d,e 的值 最后求出结果:如图 传统方法解决四则运算问题分析 编写一个方法,接...

minge0001的博客 721

设计模式——(20)解释器模式

1、定义 解释器(Interpreter)模式是一种对象的行为模式。给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 解释器模式的本质:分离实现,解释执行 2、UML类图 抽象表达式(AbstractExpression)角色:约定解释器的解释操作,主要是一个interpret()方法。 终结符表达式(TerminalExpression)角色:用来实现文法中和终结符相关的解释操作,不再包含其它的解释器,如果用组合模式来构建抽象语法.

DF10f-0001A 165

设计模式20-解释器模式

解释器模式:重复使用的场景或者需要解释的场景(了解即可不用深入了解)

weixin_37813118的博客 458

设计模式C++实现(20)——解释器模式

1. 解释器模式(Interpreter Pattern)的定义 (1)定义   给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。   ①文法:即语法规则。在解释器模式中每一个语法都将对应一个解释器对象,用来处理相应的语法规则。它对于扩展、改变文法以及增加新的文法规则都很方便。   ②解释器模式描述了如何为简单的语言定义一个文

crkres9527 5568
上一篇: 设计模式-19备忘录模式
下一篇: 设计模式-21状态模式
胖柯G
博客等级 码龄10年 453粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值