给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
这种模式通常用于需要解释执行某种语言的场景,如正则表达式、SQL解析等。
解释器模式的核心组件。
- 抽象表达式(AbstractExpression):声明一个抽象的解释操作
- 终结符表达式(TerminalExpression):实现与文法中的终结符相关的解释操作
- 非终结符表达式(NonterminalExpression):实现文法规则的解释操作
- 上下文(Context):包含解释器之外的一些全局信息
- 客户端(Client):构建表示该文法定义的语言中一个特定句子的抽象语法树
下面通过实现一个简单的数学表达式的解释器,来演示解释器模式。
抽象表达式接口。
public interface Expression {
int interpret();
}
终结符表达式实现。
public class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret() {
return number;
}
}
非终结符表达式(加法)。
public class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() + right.interpret();
}
}
非终结符表达式(减法)。
public class SubtractExpression implements Expression {
private Expression left;
private Expression right;
public SubtractExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() - right.interpret();
}
}
上下文类。
import java.util.Stack;
public class ExpressionParser {
public static Expression parse(String expression) {
Stack<Expression> stack = new Stack<>();
String[] tokens = expression.split(" ");
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
if (isOperator(token)) {
Expression left = stack.pop();
Expression right = new NumberExpression(Integer.parseInt(tokens[++i]));
Expression operator = getOperatorExpression(token, left, right);
stack.push(operator);
} else {
stack.push(new NumberExpression(Integer.parseInt(token)));
}
}
return stack.pop();
}
private static boolean isOperator(String token) {
return token.equals("+") || token.equals("-");
}
private static Expression getOperatorExpression(String operator,
Expression left,
Expression right) {
switch (operator) {
case "+": return new AddExpression(left, right);
case "-": return new SubtractExpression(left, right);
default: throw new IllegalArgumentException("Unknown operator: " + operator);
}
}
}
客户端,测试输出结果。
public class InterpreterDemo {
public static void main(String[] args) {
String expression = "1 + 2 - 3 + 4";
Expression parsedExpression = ExpressionParser.parse(expression);
int result = parsedExpression.interpret();
System.out.println(expression + " = " + result);
}
}
解释器模式为特定类型的问题提供了优雅的解决方案,但在实际应用中需要权衡其复杂性和性能影响。
总结
解释器模式通过定义语法树来实现对用户输入内容的解释执行。
解释器模式在 Java 中可能不是首选,如果遇到适用场景,可以考虑使用外部依赖库来代替。