解释器模式(Interpreter)

这篇具有很好参考价值的文章主要介绍了解释器模式(Interpreter)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

解释器模式是一种行为设计模式,可以解释语言的语法或表达式。给定一个语言,定义它的文法的一种表示,然后定义一个解释器,使用该文法来解释语言中的句子。解释器模式提供了评估语言的语法或表达式的方式。

Interpreter is a behavior design pattern. It can interpret the syntax or expressions of a language. 
Given a language, define a representation of its grammar, and then define an interpreter 
that uses the grammar to interpret sentences by the language.

结构设计

解释器模式包含如下角色:
Context,上下文,包含解释器之外的一些全局信息。
AbstractExpression,抽象表达式,声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExression,终结符表达式,实现与文法中的终结符相关联的解释操作。
NonterminalExpression,非终结符表达式,实现与文法中的非终结符相关联的解释操作,对文法中每一条规则R1、R2、…、Rn 都需要一个具体的非终结符表达式类。
Client,客户端,构建一个句子,它是TerminalExression和NonterminalExpression的实例的一个抽象语法树,然后初始化Context,并调用解释操作。
解释器模式类图表示如下:
解释器模式(Interpreter),设计模式,解释器模式,java

伪代码实现

接下来将使用代码介绍下解释器模式的实现。由于无法使用抽象的用例表示出解释器模式,所以这里会基于特定的场景给出代码示例。这里以常见的四则运算(由于除法需要特殊处理,这里暂不提供)的解析为例,
介绍下解释器模式的实现。

// 1、抽象表达式,声明一个抽象的解释操作接口
public interface Expression {
    int interpret();
}

//2、终结符表达式,实现与文法中的终结符相关联的解释操作,这里是数字  
public class NumberExpression implements Expression {
    private int number;

    public NumberExpression(int number) {
        this.number = number;
    }

    public NumberExpression(String number) {
        this.number = Integer.parseInt(number);
    }

    @Override
    public int interpret() {
        return this.number;
    }
}

// 3、非终结符表达式,实现与文法中的非终结符相关联的解释操作,这里是运算符
public class AdditionExpression implements Expression {
    private Expression firstExpression, secondExpression;

    public AdditionExpression(Expression firstExpression, Expression secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return Math.addExact(this.firstExpression.interpret(), this.secondExpression.interpret());
    }

    @Override
    public String toString() {
        return "+";
    }
}
public class SubtractionExpression implements Expression {
    private Expression firstExpression, secondExpression;

    public SubtractionExpression(Expression firstExpression, Expression secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return Math.subtractExact(this.firstExpression.interpret(), this.secondExpression.interpret());
    }

    @Override
    public String toString() {
        return "-";
    }
}
public class MultiplicationExpression implements Expression {
    private Expression firstExpression, secondExpression;

    public MultiplicationExpression(Expression firstExpression, Expression secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return Math.multiplyExact(this.firstExpression.interpret(), this.secondExpression.interpret());
    }

    @Override
    public String toString() {
        return "*";
    }
}

// 4、表达式分析器,将输入解析成表达式并执行相关的计算
public class ExpressionParser {
    private static final String ADD = "+";

    private static final String SUBTRACT = "-";

    private static final String MULTIPLY = "*";

    private static final String SPLITTER = " ";

    private LinkedList<Expression> stack = new LinkedList();

    public int parse(String str) {
        String[] tokenList = str.split(SPLITTER);
        for (String symbol : tokenList) {
            if (!isOperator(symbol)) {
                Expression numberExpression = new NumberExpression(symbol);
                stack.push(numberExpression);
            } else {
                Expression firstExpression = stack.pop();
                Expression secondExpression = stack.pop();
                Expression operator = getExpressionObject(firstExpression, secondExpression, symbol);
                if (operator == null) {
                    throw new RuntimeException("unknown symbol: " + symbol);
                }
                int result = operator.interpret();
                NumberExpression resultExpression = new NumberExpression(result);
                stack.push(resultExpression);
            }
        }
        return stack.pop().interpret();
    }

    private boolean isOperator(String symbol) {
        return symbol.equals(ADD) || symbol.equals(SUBTRACT) || symbol.equals(MULTIPLY);

    }

    private Expression getExpressionObject(Expression firstExpression, Expression secondExpression, String symbol) {
        switch (symbol) {
            case ADD:
                return new AdditionExpression(firstExpression, secondExpression);
            case SUBTRACT:
                return new SubtractionExpression(firstExpression, secondExpression);
            case MULTIPLY:
                return new MultiplicationExpression(firstExpression, secondExpression);
            default:
                return null;
        }
    }
}

// 5、客户端
public class InterpreterClient {
    public void test() {
        // (1) 定义输入
        String input = "2 1 5 + *";
        System.out.println("input is: " + input);
        // (2) 创建表达式分析器实例
        ExpressionParser expressionParser = new ExpressionParser();
        // (3) 执行分析操作
        int result = expressionParser.parse(input);
        System.out.println("result: " + result);
    }
}

获取源码可以访问github对应代码仓。

适用场景

在以下情况下可以考虑使用解释器模式:
(1)如果需要解释执行的语言中的句子,可以表示为一个抽象语法树,可以考虑使用解释器模式。如SQL 解析、符号处理引擎、正则表达式等。
(2) 对于重复出现的问题,如果可以使用简单的语言来表达,可以考虑使用解释器模式。
(3) 一个简单语法需要解释的场景,可以考虑使用解释器模式。对于简单语法,由于其文法规则较简单,使用解释器模式要优于语法分析程序。

优缺点

解释器模式有以下优点:
(1) 可扩展性好。因为该模式使用类来表示文法规则,可以使用继承来改变或扩展该文法。
(2) 易于实现简单的文法。定义抽象语法树各个节点的类的实现大体相似。
但是该模式也存在以下缺点:
(1) 可利用场景比较少。
(2) 对于复杂的文法比较难维护。包含许多规则的文法可能难以管理和维护。
(3) 会引起类膨胀。随着文法规则的复杂化,类的规模也会随之膨胀。
(4) 使用了大量的循环和递归,需要考虑效率问题。

参考

《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/mediator.html 解释器模式
https://refactoringguru.cn/design-patterns/mediator 解释器模式
https://www.runoob.com/design-pattern/mediator-pattern.html 解释器模式
https://www.cnblogs.com/adamjwh/p/10959987.html 简说设计模式——解释器模式
https://springframework.guru/gang-of-four-design-patterns/interpreter-pattern/ Interpreter Pattern文章来源地址https://www.toymoban.com/news/detail-631667.html

到了这里,关于解释器模式(Interpreter)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——解释器模式

    更多内容,前往IT-BLOG 在软件开发中,会遇到有些问题多次重复出现,而且有一定的相似性和规律性。如果将它们归纳成一种简单的表达式(例如:正则表达式等),那么这些问题实例将是该表达式的一些句子,这样就可以用 “编译原理” 中的解释器模式来实现。 【1】解释

    2024年02月03日
    浏览(62)
  • 设计模式(23)解释器模式

    一、介绍: 1、定义:解释器(Interpreter)模式是一种对象的行为模式。给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 2、组成结构: (1)AbstractExpression(抽象表达式):约定解释器的解释操作,主要是一个interpret()方

    2024年02月06日
    浏览(53)
  • 设计模式详解-解释器模式

    类型:行为型模式 实现原理:实现了一个表达式接口,该接口使用标识来解释语言中的句子 作用:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器来解释。 主要解决:一些重复的固定文法分别创建解释器会很麻烦 何时使用:某一种特定类型的问题发生的

    2024年02月12日
    浏览(55)
  • 解释器模式(Interpreter)

    解释器模式是一种行为设计模式,可以解释语言的语法或表达式。给定一个语言,定义它的文法的一种表示,然后定义一个解释器,使用该文法来解释语言中的句子。解释器模式提供了评估语言的语法或表达式的方式。 解释器模式包含如下角色: Context,上下文,包含解释器

    2024年02月14日
    浏览(40)
  • 解释器设计模式

    解释器设计模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法,并建立一个解释器来解释该语言中的句子。这种模式通常用于需要解释或执行一种特定类型的语言的场景,例如编程语言的编译器或解释器、规则引擎系统等。 关键组成部分 抽象表达式(

    2024年02月21日
    浏览(55)
  • 设计模式(行为型模式)解释器模式

       解释器模式(Interpreter Pattern) 是一种行为设计模式,用于解释特定语言或处理特定问题领域的语法或表达式。它定义了一种语言的语法表示,并使用该表示来解释语言中的句子。通常用于构建解析器、编译器和规则评估引擎等场景。 在解释器模式中,有以下关键角色:

    2024年02月20日
    浏览(50)
  • Java设计模式-解释器模式

    一、概述 如上图,设计一个软件用来进行加减计算。我们第一想法就是使用工具类,提供对应的加法和减法的工具方法。 上面的形式比较单一、有限,如果形式变化非常多,这就不符合要求,因为加法和减法运算,两个运算符与数值可以有无限种组合方式。比如 1+2+3+4+5、

    2024年01月17日
    浏览(45)
  • 设计模式之解释器模式(下)

    3)Context的作用 1.概述 在解释器模式中,环境类Context用于存储解释器之外的一些全局信息,它通常作为参数被传递到所有表达式的解释方法interpret()中,可以在Context对象中存储和访问表达式解释器的状态,向表达式解释器提供一些全局的、公共的数据,此外还可以在Context中

    2024年04月12日
    浏览(48)
  • 设计模式之解释器模式笔记

    记录下学习设计模式-解释器模式的写法。JDK使用版本为1.8版本。 意图 :定义一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 结构 : 其中: AbstractExpression 声明一个程序的解释操作,这个接口为抽象语法树中所有的结点所

    2024年02月11日
    浏览(52)
  • js设计模式:解释器模式

    对文本进行解释和编译的时候,就会用到解释器模式 比如你写了一段js代码,js引擎就会去解释并执行这段代码 webpack中的各种loader就是用来解释各种文件类型的,并将其解释为js可识别的代码

    2024年02月22日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包