模式说明:解释器模式,给定一门语言,定义它的文法表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。属于行为型模式。 适用场景:简单语法解析、表达式计算、规则引擎、脚本片段解析。
角色:
AbstractExpression(抽象表达式):定义解释方法
interpret()TerminalExpression(终结符表达式):实现文法中终结符号
NonTerminalExpression(非终结符表达式):文法中非终结符号,通常组合其他表达式
Context(上下文环境):存放全局信息,比如变量映射
Client:构建抽象语法树,调用解释
下面实现一个简单加减表达式解释器示例。
import java.util.HashMap;
import java.util.Map;
/**
* 抽象表达式
*/
abstract class AbstractExpression {
/**
* 解释方法
* @param context 上下文,存放变量值
* @return 计算结果
*/
public abstract int interpret(Map<String, Integer> context);
}
/**
* 终结符表达式:变量
*/
class VarExpression extends AbstractExpression {
private final String key;
public VarExpression(String key) {
this.key = key;
}
@Override
public int interpret(Map<String, Integer> context) {
// 从上下文中取出变量的值
return context.get(key);
}
}
/**
* 非终结符表达式:加法
*/
class AddExpression extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public AddExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) + right.interpret(context);
}
}
/**
* 非终结符表达式:减法
*/
class SubExpression extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public SubExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) - right.interpret(context);
}
}
/**
* 客户端,负责构建语法树
*/
public class InterpreterDemo {
public static void main(String[] args) {
// 表达式:a + b - c
// 构建抽象语法树
AbstractExpression a = new VarExpression("a");
AbstractExpression b = new VarExpression("b");
AbstractExpression c = new VarExpression("c");
AbstractExpression add = new AddExpression(a, b);
AbstractExpression expression = new SubExpression(add, c);
// 上下文:给变量赋值 a=10, b=20, c=5
Map<String, Integer> context = new HashMap<>();
context.put("a", 10);
context.put("b", 20);
context.put("c", 5);
// 执行解释计算
int result = expression.interpret(context);
System.out.println("a + b - c = " + result); // 输出 25
}
}
运行输出
a + b - c = 25优缺点
✅优点
易于扩展新语法,新增运算符只需要增加非终结符类;
文法规则被封装成类,语法树结构清晰。
❌缺点
文法复杂时会产生大量表达式类,类爆炸;
维护复杂语法成本很高,复杂语法不推荐使用,一般用成熟解析器框架。
实际使用场景举例
简单规则引擎:
age > 18 && score > 60SQL 解析、简单脚本解析;
正则底层也是解释器思想,但业务代码很少手写完整解释器。
提示:实际项目很少手写完整解释器,一般借助 ANTLR 等语法生成工具。
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问