意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
Given a language, define a represention for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
结构
参与者
AbstractExpression
声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExpression
实现与文法中的终结符相关联的解释操作。
一个句子中的每一个终结符需要该类的一个实例。
NonterminalExpression
Context
Client
适用性
当有个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可以使用 Interpreter 模式。
当存在以下情况时效果最好:
效果
易于改变和扩展文法。
易于实现文法。
复杂的文法难以维护。
增加了新的解释表达式的方式。
相关模式
抽象语法树是一个 Composite 模式的实例。
可以使用 Flyweight 模式在抽象语法树中共享终结符。
可以使用 Iterator 模式遍历解释器结构。
可以使用 Visitor 模式在一个类中维护抽象语法树中的各个节点的行为。
Implementation 以下是一个规则检验器实现,具有 and 和 or 规则,通过规则可以构建一颗解析树,用来检验一个文本是否满足解析树定义的规则。
例如一颗解析树为 D And (A Or (B C)),文本 “D A” 满足该解析树定义的规则。
这里的 Context 指的是 String。
1 2 3 public abstract class Expression { public abstract boolean interpret (String str) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 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); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class Client { public static Expression buildInterpreterTree () { Expression terminal1 = new TerminalExpression ("A" ); Expression terminal2 = new TerminalExpression ("B" ); Expression terminal3 = new TerminalExpression ("C" ); Expression terminal4 = new TerminalExpression ("D" ); Expression alternation1 = new OrExpression (terminal2, terminal3); Expression alternation2 = new OrExpression (terminal1, alternation1); 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)); } }
JDK