1. 意图(Intent)

为语言创建解释器,通常由语言的语法和语法分析来定义。

解释器模式的使用场景

  1. 当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树,可以使用解释器模式。而当存在以下情况时该模式效果最好
  2. 该文法的类层次结构变得庞大而无法管理。此时语法分析程序生成器这样的工具是最好的选择。他们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
  3. 效率不是一个关键问题,最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将他们装换成另一种形式,例如,正则表达式通常被装换成状态机,即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的

解释器模式优点

  1. 改变和扩展方法很容易, 因为该模式使用类来表示方法规则, 你可以使用继承来改变或扩展该方法。
  2. 实现方法比较容易, 因为定义抽象语法树总各个节点的类的实现大体类似, 这些类都易于直接编写。
  3. 解释器模式就是将一句话,转变为实际的命令程序执行而已。 而不用解释器模式本身也可以分析, 但通过继承抽象表达式的方式, 由于依赖转置原则, 使得文法的扩展和维护都带来的方便。

    解释器模式缺点

    解释器模式为方法中的每一条规则至少定义了一个类, 因此包含许多规则的方法可能难以管理和维护。 因此当方法非常复杂时, 使用其他的技术如 语法分析程序编译器生成器 来处理。

    2. 类图(Class Diagram)

    2b125bcd-1b36-43be-9b78-d90b076be549.png
  • TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression
  • Context:上下文,包含解释器之外的一些全局信息。

    3. 实现(Implementation)

    I 规则检验器案例

    以下是一个规则检验器实现,具有 and 和 or 规则,通过规则可以构建一颗解析树,用来检验一个文本是否满足解析树定义的规则。
    例如一颗解析树为 D And (A Or (B C)),文本 “D A” 满足该解析树定义的规则。
    这里的 Context 指的是 String。[ AbstarctExpression ]

    1. public abstract class Expression {
    2. public abstract boolean interpret(String str);
    3. }

    终结符表达式 [ TerminalExpression ]

    1. public class TerminalExpression extends Expression {
    2. private String literal = null;
    3. public TerminalExpression(String str) {
    4. literal = str;
    5. }
    6. public boolean interpret(String str) {
    7. StringTokenizer st = new StringTokenizer(str); // 用于分隔字符串。
    8. while (st.hasMoreTokens()) {
    9. String test = st.nextToken();
    10. if (test.equals(literal)) {
    11. return true;
    12. }
    13. }
    14. return false;
    15. }
    16. }

    [ NoTerminalExpression ]
    And 表达式具体类

    1. public class AndExpression extends Expression {
    2. private Expression expression1 = null;
    3. private Expression expression2 = null;
    4. public AndExpression(Expression expression1, Expression expression2) {
    5. this.expression1 = expression1;
    6. this.expression2 = expression2;
    7. }
    8. public boolean interpret(String str) {
    9. return expression1.interpret(str) && expression2.interpret(str);
    10. }
    11. }

    Or 表达式具体类

    1. public class OrExpression extends Expression {
    2. private Expression expression1 = null;
    3. private Expression expression2 = null;
    4. public OrExpression(Expression expression1, Expression expression2) {
    5. this.expression1 = expression1;
    6. this.expression2 = expression2;
    7. }
    8. public boolean interpret(String str) {
    9. return expression1.interpret(str) || expression2.interpret(str);
    10. }
    11. }

    客户端演示代码: ```java public class Client {

    // 构建解析树 public static Expression buildInterpreterTree() {

    1. // Literal
    2. Expression terminal1 = new TerminalExpression("A");
    3. Expression terminal2 = new TerminalExpression("B");
    4. Expression terminal3 = new TerminalExpression("C");
    5. Expression terminal4 = new TerminalExpression("D");
    6. // B Or C
    7. Expression alternation1 = new OrExpression(terminal2, terminal3);
    8. // A Or (B Or C)
    9. Expression alternation2 = new OrExpression(terminal1, alternation1);
    10. // D And (A Or (B Or C))
    11. return new AndExpression(terminal4, alternation2);

    }

    public static void main(String[] args) {

      Expression define = buildInterpreterTree();
      String context1 = "D A";
      String context2 = "A B";
      System.out.println(define.interpret(context1));
      System.out.println(define.interpret(context2));
    

    } }

// 输出结果: // true // false ```