设计模式之解释器模式

23种设计模式-解释器模式(android应用场景介绍) 解释器模式是一种行为型设计模式,它允许你定义一种语言的语法,并且使用该语法来解释和执行特定的程序。解释器模式适用于那些需要频繁修改语法的应用程序,因为它将语法解释成为一个抽象语法树,从而可以轻松地添加新的语法规则。 阅读详情

什么是解释器模式

    解释器模式定义了一个语言的文法,并且建立一个解释器来解释语言中的句子。
    解释器模式主要包含以下几个角色:
        AbstractExpression(抽象表达式):声明了抽象的解释操作。
        TerminalExpression(终结符表达式):抽象表达式的子类,实现了与文法中终结符相关的解释操作,文法中的每一个终结符都有一个终结表达式。
        NonterminalExpression(非终结符表达式):抽象表达式的子类,实现了文法中非终结符相关的解释操作,由于在非终结符表达式中可以包含终结符表达式也可以包含非终结符表达式,因此解释操作一般是递归完成。
        Context(环境):用于存储解释器之外的全局信息。

解释器模式的优缺点

优点
  1. 可以通过继承等方式改变和扩展文法。
  2. 每一个文法都可以表示为一个类,可以方便的实现一个语言。
  3. 方便的增加新的解释表达式。
缺点
  1. 对于复杂的文法可能需要定义过多的解释类,难以维护。
  2. 执行效率下,解释器模式中使用了大量的循环和递归调用,对于复杂的文法执行效率低。

解释器模式的应用场景

  1. 文法比较简单。
  2. 执行效率不是关键。
  3. 一些重复出现的问题可以用一种简单的语言来表达。
  4. 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。

解释器模式的案例

// 抽象表达式
public abstract class Expression {

    /**
     * 解释公式和数值, key 就是公式(表达式) 参数[a,b,c], value就是就是具体值
     *
     * @param var var
     * @return int
     */
    public abstract int interpreter(HashMap<String, Integer> var);

}

// 解释器
public class VarExpression extends Expression {

    private String key;

    public VarExpression(String key) {
        this.key = key;
    }

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return var.get(this.key);
    }

}


public class SymbolExpression extends Expression {

    protected Expression left;
    protected Expression right;

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

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return 0;
    }

}
public class SubExpression extends SymbolExpression {

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

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

}
public class AddExpression extends SymbolExpression {

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

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        //super.left.interpreter(var) : 返回 left 表达式对应的值 a = 10
        //super.right.interpreter(var): 返回right 表达式对应值 b = 20
        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;
        //遍历我们的字符数组, 即遍历  [a, +, b]
        //针对不同的情况,做处理
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]) {
                case '+':
                    // 从stack取出left => "a"
                    left = stack.pop();
                    // 取出右表达式 "b"
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    // 然后根据得到left 和 right 构建 AddExpresson加入stack
                    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:
                    //如果是一个 Var 就创建要给 VarExpression 对象,并push到 stack
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
                    break;
            }
        }
        //当遍历完整个 charArray 数组后,stack 就得到最后Expression
        this.expression = stack.pop();
    }

    public int run(HashMap<String, Integer> var) {
        //最后将表达式a+b和 var = {a=10,b=20}
        //然后传递给expression的interpreter进行解释执行
        return this.expression.interpreter(var);
    }
}


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.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;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/bc528554daaa4bf18bbf3f71c1b7a388.png#pic_center)

解释器模式在源码中的应用

SpelExpression
public interface Expression {

	String getExpressionString();

	@Nullable
	Object getValue() throws EvaluationException;

	@Nullable
	<T> T getValue(@Nullable Class<T> desiredResultType) throws EvaluationException;

	@Nullable
	<T> T getValue(@Nullable Object rootObject, @Nullable Class<T> desiredResultType) throws EvaluationException;

	@Nullable
	<T> T getValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Class<T> desiredResultType)
			throws EvaluationException;

	@Nullable
	Class<?> getValueType(@Nullable Object rootObject) throws EvaluationException;

	@Nullable
	TypeDescriptor getValueTypeDescriptor() throws EvaluationException;

	@Nullable
	TypeDescriptor getValueTypeDescriptor(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException;

	void setValue(@Nullable Object rootObject, @Nullable Object value) throws EvaluationException;
    ......
}


public class SpelExpression implements Expression {

	// Number of times to interpret an expression before compiling it
	private static final int INTERPRETED_COUNT_THRESHOLD = 100;

	// Number of times to try compiling an expression before giving up
	private static final int FAILED_ATTEMPTS_THRESHOLD = 100;


	private final String expression;

	private final SpelNodeImpl ast;

	@Override
	@Nullable
	public Object getValue() throws EvaluationException {
		CompiledExpression compiledAst = this.compiledAst;
		if (compiledAst != null) {
			try {
				EvaluationContext context = getEvaluationContext();
				return compiledAst.getValue(context.getRootObject().getValue(), context);
			}
			catch (Throwable ex) {
				// If running in mixed mode, revert to interpreted
				if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
					this.compiledAst = null;
					this.interpretedCount.set(0);
				}
				else {
					// Running in SpelCompilerMode.immediate mode - propagate exception to caller
					throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_RUNNING_COMPILED_EXPRESSION);
				}
			}
		}

		ExpressionState expressionState = new ExpressionState(getEvaluationContext(), this.configuration);
		Object result = this.ast.getValue(expressionState);
		checkCompile(expressionState);
		return result;
	}
    ......
}

【Java设计模式】Java设计模式之(七)解释器模式(Interpreter Pattern) 本文目录 一、解释器模式介绍 二、代码实现 步骤一 步骤二 步骤三 步骤四 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。 一、解释器模式介绍 意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 主要解决:对于一些固定文法构建一个解释句子的解释器。 何时使用:如果一种特定类型的问 阅读详情

相关推荐

【愚公系列】二十三种设计模式(十五)-解释器模式(Interpreter Pattern)

设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。

愚公智库 47万+

解释器模式及其应用场景

解释器模式(Interpreter Design Pattern)指给定一个“语言”,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。这里所指的“语言”是指使用规定格式和语法的代码。 比如说在计算器中,我们输入一个加法/减法表达式(中缀表达式)“1+6-5”字符串,就能在计算器中输出结果2。而我们知道,一般的程序语言像C++、Java和Python无法直接解释这个字符串,那么就必须定义规定格式和语法的解释器,来对这个字符串表达式进行解释成程序语言能计算的方式(后缀表达式),

hello_1566的博客 2121

保姆级教程:用GROMACS的FEP方法计算小分子结合自由能(附完整mdp配置)

本文提供了一份详细的GROMACS自由能微扰(FEP)计算教程,涵盖从系统准备、参数配置到结果分析的全流程。通过具体案例演示如何计算小分子结合自由能,包括λ窗口设计、动力学参数优化及并行化执行技巧,帮助研究者克服FEP计算中的常见问题,获得可靠的自由能数据。

weixin_30598225的博客 353

【设计模式——学习笔记】23种设计模式——解释器模式Interpreter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

讲解解释器模式的思想,介绍其常见的应用场景,举例说明其实现方式

我只管埋头前行,剩下的交给时间。 2795

野火STM32F407(骄阳)+无刷直流驱动板+永磁同步电机控制学习记录(四)(基于HAL库)

以上内容都是参考别人资料自学的,很多地方都是凭感觉,因为理论部分不太会算,只要电机能转就行,其他性能指标都没考虑,因为不会,所以这纯属是学习记录帖。带宽在500时,电流波动小,但是响应很慢,就是堵转后不太容易恢复转动。速度环带宽设定小了,响应不够快,带宽设定大了波动比较大,电机感觉起来也震一点,而且,当带宽设到200的时候,启动直接就锁死了,应该是PI增益设定太大了。电流环带宽的试验:去掉速度环,让Iq_Set=2,Ud=0,此时电机是电流环闭环控制,用手堵转电机然后松开,看电流的波动以及响应情况。

XUEXIDEXIAOhai的博客 4553

Drupal远程代码执行漏洞(CVE-2018-7600)实战复现:从检测到写入WebShell的全过程

本文详细解析了Drupal远程代码执行漏洞(CVE-2018-7600)的实战复现过程,从环境搭建、漏洞检测到WebShell写入的全流程。该高危漏洞影响Drupal 6.x至8.x版本,允许攻击者未经授权执行任意代码。文章提供了多种POC构造方法和高级利用技巧,帮助安全研究人员深入理解漏洞原理并掌握验证技术。

weixin_29322553的博客 275

设计模式之-解释器模式,快速掌握解释器模式,通俗易懂的讲解解释器模式以及它的使用场景

总结来说,解释器模式适用于需要解析和执行简单语法规则的场景,并且提供了一种灵活、可扩展的方式来处理复杂的表达式。通过将问题表示为语言规则。

咖啡程序员 1692

HC32F460 FPU实战:从零开启硬件浮点加速

本文详细介绍了如何在HC32F460开发板上启用和优化FPU(浮点运算单元),以显著提升硬件浮点运算性能。从工程配置、关键代码修改到实战优化技巧,全面解析FPU加速的实现方法,并分享常见问题的解决方案,帮助开发者避免常见陷阱,充分发挥HC32F460的硬件潜力。

weixin_42620340的博客 348

设计模式十六-解释器模式

接下来,我们使用解析器对象解析表达式并生成一个抽象语法树。它的原理是使用抽象表达式和上下文对象来构建抽象语法树,并使用该树来执行特定的操作。在Java中,可以使用抽象类和接口来实现这些组件,并使用它们来构建具体的表达式对象和解释器对象等。抽象表达式是一个抽象类或接口,它包含一个解释方法,该方法接受上下文对象作为参数,并返回解释结果。解释器模式的核心是通过使用抽象表达式对象来构建一个抽象语法树,并使用上下文对象来处理该树。它的基本原理是将一个表达式解析成一个抽象语法树,然后使用该树来执行特定的操作。

lonely_baby的博客 261

【一看就会】Autoware.universe中静态绕障路线的生成逻辑

在路径行为规划中,前期根据地图和起点终点,生成了一组连续可行的路径段序列(lanelets),然后后续路径行为规划,又会进行起始点,终止点,避障绕障路径的路径规划,并且会调用route_handler中的函数,进行中心线生成,最后生成路径,后续再给速度行为规划进行速度规划。在autoware.universe的规划中,是基于规则的规划,而其中的规则又是为了解决不同场景的。而这些场景,大部分是为了解决路上障碍物(静态、动态、行人、车辆等等)。

weixin_48386130的博客 321

在ParaView中编程实现涡量可视化

综上所述,本文介绍了在ParaView中使用编程方式实现涡量可视化的方法,并提供了相应的Python代码示例。通过灵活运用ParaView的编程接口,我们可以根据特定需求定制复杂的数据可视化流程,进一步深入了解和分析流体的旋转行为。ParaView是一款强大的开源数据可视化工具,它提供了丰富的功能和灵活的编程接口,使用户能够定制数据可视化流程。你可以根据需要自定义颜色映射范围和颜色,上述代码中的RGBPoints列表中包含了两个点,分别对应涡量值为0和10时的颜色。在实际使用过程中,你需要替换代码中的。

ByteProwl的博客 1435

设计模式 16 解释器模式 Interpreter Design Pattern

解释器模式 (Interpreter Design Pattern) 是一种行为型设计模式,它定义了一种语法表示,并提供了一种解释器来解释该语法表示的句子。核心概念:语法表示 (Grammar): 定义了语言的结构和规则,通常使用上下文无关文法 (Context-Free Grammar) 来表示。解释器 (Interpreter): 一个对象,它根据语法规则解析和执行语言的句子。主要组成部分:抽象解释器 (AbstractExpression): 定义解释器的接口,包含解释方法。

jxusthusiwen的专栏 1157

基于Qt的工业组态软件开发:图形绘制与TCP通讯实现

在数据接收时,通过 readyRead 信号触发解析函数,校验数据包完整性后提取有效数据,并更新对应图形元素的状态,例如根据温度值改变矩形的填充色,实现设备状态可视化。测试阶段,我们将软件部署到Windows工控机,连接PLC设备进行通讯测试,结果表明图形元素响应及时,TCP数据传输稳定,满足工业现场的基本需求。综上所述,基于Qt的组态软件开发,核心在于利用 QGraphicsView 框架实现图形元素的灵活绘制与管理,结合 QTcpSocket 完成工业数据的可靠交互。

谢谢大家的关注和点赞!这里只有纯纯的知识干货,没有一句废话。希望能实实在在帮到大家~要是觉得有用,别忘了给我点支持哟,你 272

设计模式 解释器模式(Interpreter Pattern)

解释器模式(Interpreter Pattern)是一种软件设计模式,属于行为型模式之一。这种模式的主要目的是定义语言的语法表示,并且提供了一个解释器来处理这种表示。解释器模式可以用于解析语言或表达式等场合,特别是在编译器、解释器和自然语言处理中应用较多。解释器模式包含以下几个主要角色: Abstract Expression 创建接口方法 Terminal Expression 对数据简单处理 Terminal Expression 是解释器模式中的一种表达式类型,它表示文法中的最基本元素,这些元素不

ling_zhi_xin的博客 1978

Open3D 从体素网格构建八叉树【2025最新版】

从体素网格构建八叉树,博客长期更新,本文最近更新时间为:2025年1月1日。

点云侠的博客 34万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

23种设计模式之解释器模式(Interpreter Pattern)

本篇文章将23种设计模式中的解释器模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

设计模式-解释器模式-Interpreter Pattern

解释器模式(Interpreter Pattern)是一种行为设计模式,它主要用于定义如何评估语言的语法或表达式,是一种用于解释执行语言的模式。这种模式涉及到创建一个表达式接口,该接口能够解释一个特定的上下文。解释器模式通常用于解析和执行语言的语法规则,如计算表达式、解析文本文件等。抽象表达式(AbstractExpression):终结符表达式(TerminalExpression):非终结符表达式(NonterminalExpression):上下文(Context):客户端(Client):需要解释一

wesigj的博客 1704

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

设计模式之解释器模式(Interpreter Pattern)

文章目录一、定义二、应用场景三、优缺点3.1、优点:3.2、缺点:3.3、 使用场景3.4、. 应用实例3.5、 注意事项四、UML类图4.1、主要角色4.2、UML类图4.3、 典型代码4.3.1、AbstractExpression 抽象表达式类,典型代码:4.3.2、TerminalExpression 终结符表达式,典型代码:4.3.3、NonterminalExpression 非终结...

猎人在吃肉 705

23种设计模式——解释器模式(Interpreter Pattern)

本文介绍了23种经典设计模式之——解释器模式(Interpreter Pattern)的使用及说明

Meteors.的博客 1016

设计模式-解释器模式(Interpreter Pattern)

解释器模式 定义 Given a language,define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表...

kaven 1376

C++设计模式——解释器模式(interpreter pattern)

一、原理讲解 1.1意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 1.2应用场景 文法简单。对于复杂的文法,文法的类层次变得庞大而无法管理;此时语法分析程序生成器这样的工具是更好的选择。它们无法构件抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。 效率不是关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器也可用解释器模式实现,该模

净无邪博客 1768

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

核心模块:抽象表达符、非终结表达符、终结表达符、环境类 所有代码请访问:git@code.aliyun.com:289804201/PatternLearn.git 使用场景:正则表达式,自定义语言,计算器; 优点:易于扩展,增加新的符号只用增加新的表达式即可; 缺点:复杂的文法难以维护,存在大量循环和递归操作,复杂的句子,速度很慢; 注意: 1,每一个

didiao11300的专栏 292

【C#设计模式】23.解释器模式(Interpreter Pattern)【行为型】

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

星Yeah 的博客 1912

设计模式(Design pattern)之解释器模式(Interpreter Pattern)

摘要:解释器模式通过抽象语法树解析语言表达式。核心包含抽象表达式类Expression及其子类:终结符表达式Variable(变量)和非终结符表达式Plus(加法)、Minus(减法)。Context类维护变量值映射关系。使用时构建表达式树(如a+(e+d+(d-e))),通过interpret()方法递归计算表达式值。该模式将语法规则表示为类层次结构,适合简单文法解析。

RR1335 之代码才是动力源 227

设计模式中的解释器模式(Interpreter Pattern)

在软件开发中,经常需要解析和执行某种特定的语法或语言,例如数学表达式计算、脚本语言解析、正则表达式匹配、SQL 解析、编译器等。如果直接在代码中硬编码解析逻辑,可能会导致代码复杂、难以扩展。解释器模式(Interpreter Pattern)提供了一种定义语言语法并解析表达式的方法,使得程序可以轻松解析并执行特定语言的语法规则,从而提高代码的可读性、可扩展性。本文将详细介绍解释器模式的概念、应用场景,并通过 Python 代码示例展示其实现方式。

950
上一篇: 设计模式之命令模式
下一篇: 设计模式之迭代器模式
geek-wmy
博客等级 码龄9年 322粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值