解释器模式将文法规则映射为java类:终结符(如numberexpression)表示基本单元,非终结符(如addexpression)表示复合结构,通过组合构建ast并递归求值;context承载变量等运行时信息;扩展文法只需新增类,符合开闭原则。

Java 中解释器模式定义语言文法,本质是把语法规则映射为类结构,而不是写 BNF 或正则表达式。它不依赖外部解析器生成工具(如 ANTLR),而是用面向对象方式将每条文法规则转化为一个 Java 类,再通过组合这些类构造抽象语法树(AST),最终递归求值。
文法即类:每条规则对应一个表达式类
解释器模式中,“文法”不是字符串描述,而是由一组继承自统一抽象表达式(AbstractExpression)的类共同构成:
-
终结符表达式(TerminalExpression):对应语言中最基本、不可再分的单元,比如数字字面量、变量名、常量。例如
NumberExpression(5)或VariableExpression("x")。 -
非终结符表达式(NonterminalExpression):对应文法中的复合规则,比如加法、乘法、括号、函数调用等。每个操作符或结构都封装为一个类,如
AddExpression(left, right)、MultiplyExpression(left, right)。 - 所有表达式类都实现同一个
interpreter(Context context)方法,具体行为由各自类内部定义。
用类组合模拟语法结构
用户输入的句子(如 "a + 3 * b")不会被直接字符串处理,而是先被词法/语法分析器(可手写或用工具辅助)构造成对象树:
- 先拆出原子:变量
a→VariableExpression("a"),数字3→NumberExpression(3),变量b→VariableExpression("b"); - 再按优先级和结合性组装:乘法优先,所以
3 * b构造成MultiplyExpression(new NumberExpression(3), new VariableExpression("b")); - 最后整体是
AddExpression(new VariableExpression("a"), 上述乘法对象)。
这棵树就是该句子的“文法表示”,也是解释执行的依据。
Context 承载运行时上下文
文法执行需要环境支持,比如变量值查找、函数绑定、错误状态等。Context 是一个普通 Java 类,用于传递和共享这些信息:
- 常见字段包括:
Map<string object> variables</string>存变量值,Stack<object> stack</object>支持嵌套作用域,甚至Locale或TimeZone等业务相关上下文; - 每个
interpreter()方法都接收这个 Context,并从中读取所需数据(如context.getValue("a")); - Context 不参与文法定义,但让文法具备实际执行能力——没有它,变量和外部状态就无法接入。
文法扩展靠新增类,不改已有逻辑
定义文法不是修改一个配置文件,而是增加 Java 类。例如要支持减法:
- 新增
SubtractExpression extends AbstractExpression,实现自己的interpreter(); - 在解析阶段,当识别到
-操作符时,创建SubtractExpression(left, right)实例并加入 AST; - 原有加法、乘法、变量等类完全不动,也不影响已构建的树结构。
这种设计让文法演进清晰可控,也符合开闭原则。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











