解释器
更新: 6/28/2025 字数: 0 字 时长: 0 分钟
定义
解释器模式 (Interpreter Pattern) 给定一个语言,定义它的文法表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。它主要用于需要解释执行的语言,如正则表达式、SQL 解析等。
角色
- 抽象表达式 (Abstract Expression):声明解释操作的接口
- 终结符表达式 (Terminal Expression):实现文法中终结符的解释
- 非终结符表达式 (Nonterminal Expression):实现文法规则的解释
- 上下文 (Context):包含解释器之外的信息
- 客户端 (Client):构建语法树并调用解释操作
实现
布尔表达式解释器
java
// 抽象表达式
public interface Expression {
boolean interpret(String context);
}
// 终结符表达式
public class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
@Override
public boolean interpret(String context) {
return context.contains(data);
}
}
// 非终结符表达式:AND
public class AndExpression implements Expression {
private Expression expr1;
private Expression expr2;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
// 非终结符表达式:OR
public class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
// 非终结符表达式:NOT
public class NotExpression implements Expression {
private Expression expr;
public NotExpression(Expression expr) {
this.expr = expr;
}
@Override
public boolean interpret(String context) {
return !expr.interpret(context);
}
}
// 客户端使用
public class InterpreterDemo {
// 规则:Robert 和 John 是男性
public static Expression getMaleExpression() {
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
// 规则:Julie 是已婚女性
public static Expression getMarriedWomanExpression() {
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}
public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married woman? " +
isMarriedWoman.interpret("Married Julie"));
}
}
数学表达式解释器
java
// 抽象表达式
public interface MathExpression {
int interpret(Map<String, Integer> context);
}
// 变量表达式
public class VariableExpression implements MathExpression {
private String name;
public VariableExpression(String name) {
this.name = name;
}
@Override
public int interpret(Map<String, Integer> context) {
return context.getOrDefault(name, 0);
}
}
// 数字表达式
public class NumberExpression implements MathExpression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret(Map<String, Integer> context) {
return number;
}
}
// 加法表达式
public class AddExpression implements MathExpression {
private MathExpression left;
private MathExpression right;
public AddExpression(MathExpression left, MathExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) + right.interpret(context);
}
}
// 减法表达式
public class SubtractExpression implements MathExpression {
private MathExpression left;
private MathExpression right;
public SubtractExpression(MathExpression left, MathExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) - right.interpret(context);
}
}
// 乘法表达式
public class MultiplyExpression implements MathExpression {
private MathExpression left;
private MathExpression right;
public MultiplyExpression(MathExpression left, MathExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) * right.interpret(context);
}
}
// 客户端使用
public class MathInterpreterDemo {
public static void main(String[] args) {
// 创建表达式:a + b * c
MathExpression a = new VariableExpression("a");
MathExpression b = new VariableExpression("b");
MathExpression c = new VariableExpression("c");
MathExpression expr = new AddExpression(
a,
new MultiplyExpression(b, c)
);
// 设置上下文
Map<String, Integer> context = new HashMap<>();
context.put("a", 10);
context.put("b", 5);
context.put("c", 2);
// 解释执行
int result = expr.interpret(context);
System.out.println("结果:" + result); // 输出:20
}
}
优缺点
优点:
- 易于扩展文法
- 实现文法简单直接
- 适合领域特定语言 (DSL)
- 符合单一职责原则
- 可与其他模式结合使用
缺点:
- 复杂文法难以维护
- 执行效率较低
- 类数量可能爆炸
- 难以处理复杂语法
- 不易调试
应用场景
- 正则表达式引擎
- SQL 解析器
- 编译器实现
- 规则引擎系统
- 数学公式计算
- 配置文件解析
- 机器人指令解释
与其他模式的关系
- 与组合模式:抽象语法树是组合模式的应用
- 与访问者模式:可用于遍历抽象语法树
- 与享元模式:共享终结符表达式
- 与迭代器模式:遍历表达式结构
- 与备忘录模式:保存解释状态
JDK 中的解释器模式
- Java 正则表达式(Pattern, Matcher)
- Java EL 表达式(javax.el)
- Java 编译器 API(javax.tools)
- Spring 表达式语言(SpEL)
- XML 解析器(DOM, SAX)
- Java 注解处理器
注意事项
- 避免复杂文法(维护困难)
- 考虑性能优化(缓存解释结果)
- 设计合理的抽象语法树
- 处理错误和异常情况
- 支持扩展语法
- 使用其他模式辅助实现
- 考虑内存管理(表达式对象)