设计模式之解释器模式

11. 解释器模式

  • 定义:

    ​ 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

  • 使用场景:

    1. 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
    2. 一些重复出现的问题可以用一种简单的语言来表达。
    3. 一个简单语法需要解释的场景。
    4. 正则表达式、编译器、机器人等等。
  • UML:

    1. AbstractExpression:在抽象表达式中声明了抽象的解释操作,它是所有终结符表达式和非终结符表达式的公共父类。
    2. TerminalExpression(终结符表达式):终结符表达式是抽象表达式的子类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例。通常在一个解释器模式中只有少数几个终结符表达式类,它们的实例可以通过非终结符表达式组成较为复杂的句子。
    3. NonterminalExpression(非终结符表达式):非终结符表达式也是抽象表达式的子类,它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此其解释操作一般通过递归的方式来完成。
    4. Context(环境类):环境类又称为上下文类,它用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。

在这里插入图片描述

  • 优点:

    1. 易于改变和扩展文法。
    2. 方便的实现一个简单的语言。
    3. 实现文法比较容易。
    4. 增加新的逻辑表达式比较方便。
  • 缺点:

    1. 出现大量的递归,效率比较低。
    2. 解释器模式会导致类膨胀,也就是增多。
    3. 类多、递归多,导致调试起来比较麻烦。
  • 样例:

    public interface Interpreter {
        int interpret();
    }
    
    public class NumberInterpreter implements Interpreter {
        private int number;
    
        public NumberInterpreter(int number) {
            this.number = number;
        }
    
        public NumberInterpreter(String number) {
            this.number = Integer.parseInt(number);
        }
    
        @Override
        public int interpret() {
            return this.number;
        }
    }
    
    // 加法
    public class AddInterpreter implements Interpreter {
        private Interpreter firstExpression, secondExpression;
        public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
            this.firstExpression = firstExpression;
            this.secondExpression = secondExpression;
        }
        @Override
        public int interpret() {    
            return this.firstExpression.interpret() + this.secondExpression.interpret();
        }
        @Override
        public String toString() {
            return "+";
        }
    }
    
    // 乘法
    public class MultiInterpreter implements Interpreter {
        private Interpreter firstExpression, secondExpression;
    
        public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
            this.firstExpression = firstExpression;
            this.secondExpression = secondExpression;
        }
        @Override
        public int interpret() {
            return this.firstExpression.interpret() * this.secondExpression.interpret();
        }
        @Override
        public String toString() {
            return "*";
        }
    }
    
    public class OperatorUtil {
        public static boolean isOperator(String symbol) {
            return (symbol.equals("+") || symbol.equals("*"));
    
        }
        public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
            if ("+".equals(symbol)) {  // 加法
                return new AddInterpreter(firstExpression, secondExpression);
            } else if ("*".equals(symbol)) {    // 乘法
                return new MultiInterpreter(firstExpression, secondExpression);
            } else {
                throw new RuntimeException("不支持的操作符:" + symbol);
            }
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            String inputStr = "6 100 11 + *";
            MyExpressionParser expressionParser = new MyExpressionParser();
            int result = expressionParser.parse(inputStr);
            System.out.println("解释器计算结果: " + result);
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值