[解释器设计模式详解]C/Java/Go/JS/TS/Python不同语言实现

科技资讯 投稿 5500 0 评论

[解释器设计模式详解]C/Java/Go/JS/TS/Python不同语言实现

简介

解释器模式常用于对简单语言的编译或分析实例中,为了掌握好它的结构与实现,必须先了解编译原理中的“文法、句子、语法树”等相关概念。

 

作用

    可扩展性比较好,灵活,增加了新的解释表达式的方式,易于实现简单文法。
  1. 在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

 

实现步骤

    创建抽象表达式接口(Expression),各种表达式都要实现该接口。
  1. 分别创建最终表达式和非最终表达式。最终表达式(这里是VarExpression)没有子级,直接解释表达式。非最终表达式(这里是AddExpression和SubtractExpression)是维护子表达式的容器,并将解释请求转发给这些表达式。
  2. 创建上下文环境类(这里是Context),用来表达式求值时构建执行环境。
  3. 客户端调用时先建立执行上下文环境,然后声明变量,再进行计算。

 

UML

 

Java代码

 

抽象表达式接口

 

// Expression.java 抽象表达式接口,根据业务场景规范表达式 public interface Expression { public int interpret(Context context; }

 

具体表达式实现

 

// AddExpression.java 具体表达式,实现了抽象表达式接口 public class AddExpression implements Expression { private Expression exprOne = null; private Expression exprTwo = null; public AddExpression(Expression exprOne, Expression exprTwo { this.exprOne = exprOne; this.exprTwo = exprTwo; } // 覆盖表达式,执行context对象 @Override public int interpret(Context context { System.out.println(this.getClass(.getName( + "::interpret( [context = " + context.getClass(.getName( + "]"; return exprOne.interpret(context + exprTwo.interpret(context; } }

 

// SubtractExpression.java 具体表达式,实现了抽象表达式接口 public class SubtractExpression implements Expression { private Expression exprOne = null; private Expression exprTwo = null; public SubtractExpression(Expression exprOne, Expression exprTwo { this.exprOne = exprOne; this.exprTwo = exprTwo; } // 覆盖表达式,执行context对象 @Override public int interpret(Context context { System.out.println(this.getClass(.getName( + "::interpret( [context = " + context.getClass(.getName( + "]"; return exprOne.interpret(context - exprTwo.interpret(context; } }

 

// VarExpression.java 变量表达式,或者叫终端表达式,其他表达式求值时通过层层追溯最后指向这里 // 变量与执行环境的Key对应,最终会通过key获取传入的值 public class VarExpression implements Expression { private String key; public VarExpression(String key { this.key = key; } @Override // 覆盖表达式,根据key获取变量 public int interpret(Context context { return context.get(key; } }

 

执行环境类

 

// Context.java 构建可执行环境上下文 public class Context { private Map<String, Integer> map = new HashMap<>(; public Context(String key, int value { this.add(key, value; } public Context( { } public void add(String key, int value { map.put(key, value; } public int get(String key { return map.get(key; } }

 

// Application.java 调用程序,组织各种解释器
    /*
     * 解释器模式先构建执行上下文Context,然后构建一个最终的获取值的表达式VarExpression,这就构成了含上下文和变量-值的基本环境。
     * 再将基本环境放到工具表达式里AddExpression或SubtractExpreesion进行计算,最终得到结果。
     */

   // 构建两个数相加的例子
   public static int addTwo(int one, int two {
      // 构建执行上下文环境
      Context context = new Context(;
      context.add("one", one;
      context.add("two", two;

      // 构建表达式
      VarExpression varOne = new VarExpression("one";
      VarExpression varTwo = new VarExpression("two";

      // 再构建变量来进行计算,看起来啰嗦,但这样构建多种不同表达式计算就变得简单
      Expression result = new AddExpression(varOne, varTwo;
      return result.interpret(context;
   }

   // 构建连加计算的例子
   public static int addMore(int... numbers {
      if (numbers.length <= 1 {
         return numbers[0];
      }

      Context context = new Context(;
      // 构建执行环境
      for (int num : numbers {
         context.add("num" + num, num;
      }

      // 先取出前两个作为计算基础
      VarExpression varOne = new VarExpression("num" + numbers[0];
      VarExpression varTwo = new VarExpression("num" + numbers[1];
      // 再构建表达式,先赋值前两个
      Expression expression = new AddExpression(varOne, varTwo;

      // 如果只有两个数则直接返回计算结果
      if (numbers.length == 2 {
         return expression.interpret(context;
      }

      // 如果数量超过两个则累加表达式再求值
      for (int i = 2; i < numbers.length; i++ {
         Expression nextExpression = new VarExpression("num" + numbers[i];
         // 表达式不断累加
         expression = new AddExpression(expression, nextExpression;
      }

      return expression.interpret(context;
   }

   // 计算前两个数相加,再减去后一个数的计算例子
   public static int addAndSubtract(int one, int two, int three {
      // 构建执行上下文环境,有3个可操作的域
      Context context = new Context(;
      context.add("one", one;
      context.add("two", two;
      context.add("three", three

编程笔记 » [解释器设计模式详解]C/Java/Go/JS/TS/Python不同语言实现

赞同 (29) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽