小易说IT 小易说IT

Java 解释器模式(Interpreter)示例代码

模式说明:解释器模式,给定一门语言,定义它的文法表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。属于行为型模式。 适用场景:简单语法解析、表达式计算、规则引擎、脚本片段解析。

角色:

  1. AbstractExpression(抽象表达式):定义解释方法 interpret()

  2. TerminalExpression(终结符表达式):实现文法中终结符号

  3. NonTerminalExpression(非终结符表达式):文法中非终结符号,通常组合其他表达式

  4. Context(上下文环境):存放全局信息,比如变量映射

  5. 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

优缺点

✅优点

  1. 易于扩展新语法,新增运算符只需要增加非终结符类;

  2. 文法规则被封装成类,语法树结构清晰。

❌缺点

  1. 文法复杂时会产生大量表达式类,类爆炸;

  2. 维护复杂语法成本很高,复杂语法不推荐使用,一般用成熟解析器框架。

实际使用场景举例

  • 简单规则引擎:age > 18 && score > 60

  • SQL 解析、简单脚本解析;

  • 正则底层也是解释器思想,但业务代码很少手写完整解释器。

提示:实际项目很少手写完整解释器,一般借助 ANTLR 等语法生成工具。


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/java-interpreter-pattern-example-code

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/