解释器模式 (Interpreter Pattern)
📋 Research Summary
解释器模式用于定义特定领域语言(DSL)的语法解释。在正则表达式引擎、SQL 解析器、配置文件解析、数学表达式计算中有应用。但对于复杂语法,通常使用专门的解析器生成器(如 ANTLR、Yacc)替代。
🌱 逻辑原点
如果用户想搜索 "(apple OR banana) AND NOT rotten",你如何理解这个查询并转化为实际的过滤逻辑?如果明天用户想要 "NEAR" 操作符,你的代码需要怎么改?
自然语言需求与程序执行逻辑的矛盾:用户想用接近自然语言的方式表达,但程序只能执行确定的指令。

🧠 苏格拉底式对话
1️⃣ 现状:最原始的解法是什么?
用正则表达式或字符串处理:
python
def search(query):
if "AND" in query:
parts = query.split("AND")
return search(parts[0]) and search(parts[1])
elif "OR" in query:
parts = query.split("OR")
return search(parts[0]) or search(parts[1])
# ... 越来越复杂的字符串处理
优点 :简单快速,适合非常简单的场景。
问题:难以处理嵌套、优先级、复杂的语法规则。
2️⃣ 瓶颈:规模扩大 100 倍时会在哪里崩溃?
当查询语言变得复杂时:
- 嵌套地狱 :
(A AND (B OR (C AND D)))这种嵌套用字符串处理几乎不可能 - 优先级问题 :
A AND B OR C是(A AND B) OR C还是A AND (B OR C)? - 扩展困难:增加新操作符需要修改所有解析代码
- 无法复用:解析逻辑与执行逻辑混在一起
核心矛盾:我们需要一种系统化的方法来"理解"语言结构,而不是简单的字符串匹配。
3️⃣ 突破:必须引入什么新维度?
将语法规则建模为对象树。
不是"处理字符串",而是"构建抽象语法树(AST)"。每个语法规则变成一个类,表达式被解析为一棵树,解释器通过遍历树来执行:
查询字符串 --解析--> AST(AndExpression、OrExpression、NotExpression...)
--遍历--> 执行结果
这就是解释器的本质:将语言语法建模为类层次结构,用树形结构表示表达式。
📊 视觉骨架
例如
例如
例如
例如
包含
包含
表达式 Expression
终结符 Terminal
非终结符 Non-Terminal
数字 Number
变量 Variable
加法 Add
减法 Subtract
左表达式 Left
右表达式 Right
关键洞察:解释器模式将语法规则编码为类。终结符表达式(如数字、变量)没有子节点,非终结符表达式(如加减乘除)包含子表达式。解释就是递归遍历这棵树。
⚖️ 权衡模型
公式:
Interpreter = 解决了领域语言的表达 + 牺牲了执行效率 + 增加了语法复杂度限制
代价分析:
- ✅ 解决: 领域特定语言(DSL)、语法规则清晰可扩展、解析与执行分离、易于修改文法
- ❌ 牺牲: 执行效率(递归解释比编译执行慢)、复杂文法难以维护
- ⚠️ 增加: 类的数量(每个语法规则一个类)、内存开销(AST 树)、学习成本(需要理解文法和 AST)
使用建议:当需要定义简单的领域特定语言,且语法规则相对稳定时使用。对于复杂语法,建议使用 ANTLR 等专业解析器生成器。典型场景:配置文件解析、简单查询语言、规则引擎、数学表达式计算。
🔁 记忆锚点
python
class Expression(ABC):
"""
解释器的本质:将语法建模为对象树
"""
@abstractmethod
def interpret(self, context: Dict) -> float:
"""解释表达式"""
pass
class Number(Expression):
"""终结符表达式:数字"""
def __init__(self, value: float):
self._value = value
def interpret(self, context: Dict) -> float:
return self._value
class Add(Expression):
"""非终结符表达式:加法"""
def __init__(self, left: Expression, right: Expression):
self._left = left
self._right = right
def interpret(self, context: Dict) -> float:
# 递归解释子表达式
return self._left.interpret(context) + self._right.interpret(context)
# 构建表达式树: (1 + 2) + 3
expr = Add(Add(Number(1), Number(2)), Number(3))
result = expr.interpret({}) # 递归计算
一句话本质: 解释器模式 = 将语法规则建模为类,用树形结构表示和计算表达式。