c++如何实现解释器模式 c++设计模式之Interpreter【实例】
发布时间 - 2025-12-25 00:00:00 点击率:次解释器模式在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 override { return value; }
};
clas
s 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()辅助调试 - 上下文传递要精简 —— 避免把整个环境传入,只传必要数据(如变量表、作用域链)
它真正擅长的是“小而活”:规则常变、语法可控、团队需快速定制逻辑(如运营后台的用户筛选条件)。
# 字节
# 栈
# c++
# 作用域
# 封装
# 标识符
# 字符串
# 递归
# 指针
# 继承
# 虚函数
# 接口
# 对象
# 布尔
# 适用于
# 的是
# 不高
# 可将
# 第三方
# 建立一个
# 都走
# 应考虑
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
php485函数参数是什么意思_php485各参数详细说明【介绍】
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
千库网官网入口推荐 千库网设计创意平台入口
实例解析angularjs的filter过滤器
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
Android滚轮选择时间控件使用详解
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
如何在IIS中配置站点IP、端口及主机头?
如何确认建站备案号应放置的具体位置?
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID
如何用PHP快速搭建CMS系统?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
网站制作免费,什么网站能看正片电影?
JS弹性运动实现方法分析
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
EditPlus 正则表达式 实战(3)
Win11关机界面怎么改_Win11自定义关机画面设置【工具】
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
Android实现代码画虚线边框背景效果
Laravel如何使用Sanctum进行API认证?(SPA实战)
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
Laravel如何使用Livewire构建动态组件?(入门代码)
如何在云主机上快速搭建多站点网站?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
浅析上传头像示例及其注意事项
长沙企业网站制作哪家好,长沙水业集团官方网站?
phpredis提高消息队列的实时性方法(推荐)
Laravel如何配置Horizon来管理队列?(安装和使用)
Laravel如何使用Vite进行前端资源打包?(配置示例)
如何用虚拟主机快速搭建网站?详细步骤解析
开心动漫网站制作软件下载,十分开心动画为何停播?
Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
UC浏览器如何设置启动页 UC浏览器启动页设置方法
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
如何自定义建站之星网站的导航菜单样式?
下一篇:Nginx安全性问题与应对策略
下一篇:Nginx安全性问题与应对策略


s 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