c++如何实现解释器模式 c++设计模式之Interpreter【实例】
#技术教程 发布时间: 2025-12-25
解释器模式在C++中用于定义语言文法并构建解释器,适用于语法简单、执行频率低但需灵活扩展的场景,如布尔表达式计算;核心由AbstractExpression、TerminalExpression、NonterminalExpression和Context组成,通过递归下降解析器构建表达式树。
解释器模式(Interpreter Pattern)在 C++ 中用于定义语言的文法,并建立一个解释器来解释该语言中的句子。它适用于语法简单、执行频率不高、但需要灵活扩展语法规则的场景,比如简易表达式计算、配置脚本解析、规则引擎条件表达式等。
核心结构:抽象表达式 + 终结符/非终结符表达式
解释器模式的关键是将每个语法规则映射为一个类,所有表达式类型统一继承自抽象基类 Expression,并实现 interpret() 接口:
-
AbstractExpression:声明解释操作的接口(如
interpret(Context&)) - TerminalExpression:对应终结符(如数字、变量名),不再分解,直接返回结果
-
NonterminalExpression:对应非终结符(如加、减、括号),内部持有子表达式,递归调用
interpret() - Context:封装解释器外部信息(如变量值表、全局状态)
实战示例:简易布尔表达式解释器
支持 AND、OR、NOT 和布尔字面量(True/False),输入字符串如 "True AND (NOT False)",输出 true 或 false。
关键代码片段(简化版):
class Context {
public:
std::map variables;
};
class Expression {
public:
virtual bool interpret(const Context& ctx) const = 0;
virtual ~Expression() = default;
};
class BooleanLiteral : public Expression {
bool value;
public:
explicit BooleanLiteral(bool v) : value(v) {}
bool interpret(const Context&) const ov
erride { return value; }
};
class VariableExpression : public Expression {
std::string name;
public:
explicit VariableExpression(const std::string& n) : name(n) {}
bool interpret(const Context& ctx) const override {
auto it = ctx.variables.find(name);
return it != ctx.variables.end() ? it->second : false;
}
};
class NotExpression : public Expression {
std::unique_ptr expr;
public:
explicit NotExpression(std::unique_ptr e) : expr(std::move(e)) {}
bool interpret(const Context& ctx) const override {
return !expr->interpret(ctx);
}
};
class AndExpression : public Expression {
std::unique_ptr left, right;
public:
AndExpression(std::unique_ptr l, std::unique_ptr r)
: left(std::move(l)), right(std::move(r)) {}
bool interpret(const Context& ctx) const override {
return left->interpret(ctx) && right->interpret(ctx);
}
};
配合简易词法/语法分析(如递归下降解析器),即可将字符串构造成表达式树并执行。
如何构建表达式树?——手写递归下降解析器
不依赖第三方库时,可手写轻量解析器。例如对 "a AND NOT b",按优先级(括号 > NOT > AND/OR)分步解析:
- 先识别标识符或字面量 → 构造
VariableExpression或BooleanLiteral - 遇到
NOT→ 读取下一个表达式,包装成NotExpression - 遇到
AND→ 左侧已解析部分为左操作数,右侧递归解析为右操作数,组合成AndExpression - 用栈或智能指针管理内存(推荐
std::unique_ptr)避免泄漏
注意事项与适用边界
解释器模式不是万能的,需注意:
- 语法越复杂,类爆炸越严重 —— 超过 5–6 类非终结符就应考虑用 ANTLR 或手写 LL(1) 解析器替代
- 性能敏感场景慎用 —— 每次执行都走虚函数调用+对象创建,不如编译为字节码或直接生成 C++ 代码
- 调试困难 —— 表达式树结构隐含在对象关系中,建议添加
toString()辅助调试 - 上下文传递要精简 —— 避免把整个环境传入,只传必要数据(如变量表、作用域链)
它真正擅长的是“小而活”:规则常变、语法可控、团队需快速定制逻辑(如运营后台的用户筛选条件)。
技术教程SEO上一篇 : iPhone13mini怎样查候补购票进度_iPhone13mini查候补购票进度【流程】
下一篇 : 霸气煌雷龙与锁刃龙!《怪物猎人:荒野》设计草图公开
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!
erride { return value; }
};
class VariableExpression : public Expression {
std::string name;
public:
explicit VariableExpression(const std::string& n) : name(n) {}
bool interpret(const Context& ctx) const override {
auto it = ctx.variables.find(name);
return it != ctx.variables.end() ? it->second : false;
}
};
class NotExpression : public Expression {
std::unique_ptr