Java解释器模式
解释器模式定义语言的文法,并提供解释器来解释语言中的句子。
模式定义
意图:给定语言,定义文法表示,并定义解释器解释句子。
适用场景
- 需要解释特定语法
- 简单语言解释
- 正则表达式引擎
- SQL解析器
模式结构
抽象表达式
Java
public interface Expression {
int interpret();
}
终结符表达式
Java
public class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
public NumberExpression(String number) {
this.number = Integer.parseInt(number);
}
@Override
public int interpret() {
return number;
}
}
非终结符表达式
Java
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();
}
}
public class MultiplyExpression implements Expression {
private Expression left;
private Expression right;
public MultiplyExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() * right.interpret();
}
}
环境类
Java
public class Calculator {
private Expression expression;
public Calculator(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(tokens[++i]);
stack.push(createExpression(token, left, right));
} else {
stack.push(new NumberExpression(token));
}
}
this.expression = stack.pop();
}
private boolean isOperator(String token) {
return "+".equals(token) || "-".equals(token) || "*".equals(token);
}
private Expression createExpression(String operator,
Expression left, Expression right) {
switch (operator) {
case "+": return new AddExpression(left, right);
case "-": return new SubtractExpression(left, right);
case "*": return new MultiplyExpression(left, right);
default: throw new IllegalArgumentException();
}
}
public int calculate() {
return expression.interpret();
}
}
使用示例
Java
Calculator calculator = new Calculator("1 + 2 + 3");
System.out.println(calculator.calculate()); // 6
Calculator calc2 = new Calculator("10 - 2 * 3");
System.out.println(calc2.calculate()); // 4
表达式树结构
Java
+
/ \
+ 3
/ \
1 2
递归调用interpret(),从叶子节点向上计算。
实际应用示例
简单规则引擎
text
public interface RuleExpression {
boolean interpret(Context context);
}
public class VariableExpression implements RuleExpression {
private String variable;
public VariableExpression(String variable) {
this.variable = variable;
}
@Override
public boolean interpret(Context context) {
return context.get(variable);
}
}
public class AndExpression implements RuleExpression {
private RuleExpression left;
private RuleExpression right;
public AndExpression(RuleExpression left, RuleExpression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(Context context) {
return left.interpret(context) && right.interpret(context);
}
}
public class OrExpression implements RuleExpression {
private RuleExpression left;
private RuleExpression right;
public OrExpression(RuleExpression left, RuleExpression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(Context context) {
return left.interpret(context) || right.interpret(context);
}
}
public class Context {
private Map<String, Boolean> variables = new HashMap<>();
public void set(String variable, boolean value) {
variables.put(variable, value);
}
public boolean get(String variable) {
return variables.getOrDefault(variable, false);
}
}
// 使用
Context context = new Context();
context.set("A", true);
context.set("B", false);
RuleExpression rule = new AndExpression(
new VariableExpression("A"),
new OrExpression(
new VariableExpression("B"),
new VariableExpression("C")
)
);
System.out.println(rule.interpret(context)); // true && (false || false) = false
解释器模式优点
- 易于扩展新语法规则
- 语法表示直观
- 易于实现简单语言
解释器模式缺点
- 类数量多,复杂语法维护困难
- 递归调用效率较低
- 不适合复杂语法(应使用Parser)
适用场景
- 简单语言解释
- 正则表达式
- 数学表达式计算
- 规则引擎
注意事项
复杂语法不建议使用解释器模式
可结合组合模式构建表达式树
实际应用中常使用现有解析器(ANTLR等)
解释器效率较低,不适合高性能场景
要点总结
- 解释器模式定义语法,解释句子
- Expression接口定义interpret()方法
- 终结符表达式表示叶子节点(数字、变量)
- 非终结符表达式组合其他表达式(运算符)
- 适合简单语言,复杂语法用专用解析器
📝 发现内容有误?点击此处直接编辑