1. 应用场景

给定一个语言后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。(如:360读取lua脚本,这个细节的实现就是解释器模式)

2.概念

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

3. Class Diagram

  • TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression。
  • NoTerminalExpression:没有终结符表达式
  • Context:上下文,包含解释器之外的一些全局信息。

Java设计模式(十九):解释器设计模式

4. Implementation

以下是一个规则检验器实现,具有 and 和 or 规则,通过规则可以构建一颗解析树,用来检验一个文本是否满足解析树定义的规则。

例如一颗解析树为 D And (A Or (B C)),文本 “D A” 满足该解析树定义的规则。

这里的 Context 指的是 String。

public abstract class Expression {
    public abstract boolean interpret(String str);
}
public class TerminalExpression extends Expression {

    private String literal = null;

    public TerminalExpression(String str) {
        literal = str;
    }

    public boolean interpret(String str) {
        StringTokenizer st = new StringTokenizer(str);
        while (st.hasMoreTokens()) {
            String test = st.nextToken();
            if (test.equals(literal)) {
                return true;
            }
        }
        return false;
    }
}
public class AndExpression extends Expression {

    private Expression expression1 = null;
    private Expression expression2 = null;

    public AndExpression(Expression expression1, Expression expression2) {
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    public boolean interpret(String str) {
        return expression1.interpret(str) && expression2.interpret(str);
    }
}
public class OrExpression extends Expression {
    private Expression expression1 = null;
    private Expression expression2 = null;

    public OrExpression(Expression expression1, Expression expression2) {
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    public boolean interpret(String str) {
        return expression1.interpret(str) || expression2.interpret(str);
    }
}
public class Client {

    /**
     * 构建解析树
     */
    public static Expression buildInterpreterTree() {
        // Literal
        Expression terminal1 = new TerminalExpression("A");
        Expression terminal2 = new TerminalExpression("B");
        Expression terminal3 = new TerminalExpression("C");
        Expression terminal4 = new TerminalExpression("D");
        // B C
        Expression alternation1 = new OrExpression(terminal2, terminal3);
        // A Or (B C)
        Expression alternation2 = new OrExpression(terminal1, alternation1);
        // D And (A Or (B C))
        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

5. 优点和缺点

5.1 优点

  • 将每一个语法规则表示成一个类,方便实现语言。
  • 因为语法由许多类表示,所有你可以轻易的改变或者扩展此语言
  • 通过在类结构中加入新的方法,可以在解释的同时增加新的行为,列如打印格式化的美化。

5.2 用途和缺点

  • 当你需要实现一个简单的语言时,使用解释器。
  • 当你有一个简单的语法,而且简单比效率更重要的时候,使用解释器。
  • 可以处理脚本语言和编程语言
  • 当语法规则的数目太大的时候,这个模式可能会变得非常繁杂。在这种情况下,使用解释器/编译器的产生器可能更加合适。

6. JDK

相关文章:

  • 2021-11-09
  • 2020-05-23
  • 2018-12-12
  • 2021-12-11
  • 2021-09-12
  • 2021-10-04
  • 2021-07-01
  • 2022-02-21
猜你喜欢
  • 2021-04-22
  • 2021-11-23
  • 2021-07-04
  • 2021-05-18
  • 2022-12-23
  • 2021-09-26
  • 2018-06-27
相关资源
相似解决方案