设计模式之解释器模式(C++)
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、解释器模式是什么?
解释器模式是一种行为型的软件设计模式,定义了一个解释器,来解释给定语言和文法的句子。也可以理解为翻译吧,比如1+1,翻译为一加上一,等于二,这样就做成了一个简单的加法计算器。
解释器模式的优点:
- 良好扩展性。语法的翻译通过类来实现,扩展类可以扩展其解释能力。
- 易实现。语法树中每个表达式节点类具备一定相似性,实现起来相对容易。
解释器模式的缺点:
- 执行效率低。解释器中通常有大量循环和递归语句,当被解释句子较复杂时,程序的性能受到较大影响。
- 类膨胀。规则较多时,类数量也膨胀。
二、解释器模式
2.1 结构图
客户端即Main主函数,客户端通过解释器来解析表达式内容,表达式又分为终结型和非终结型。就拿计算器举例,1+1,1就是终结符类型,表达式可以用它结尾;而+就是非终结符类型,出现了+,就意味着它前后还有别的表达式字符,自然不能作终结。

2.2 代码示例
场景描述:实现简单的加减法计算器。
//Interpreter.h
/****************************************************/
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>using namespace std;// 抽象表达式类
class Expression
{
public:// 解释virtual int interpret() = 0;};// 数字表达式类
class NumberExpression : public Expression
{
public:// 构造函数NumberExpression(int num) : number(num) {}// 解释virtual int interpret() { return number; }private:int number;
};// 加法表达式类
class AddExpression : public Expression
{
public:// 构造函数AddExpression(Expression* left, Expression* right) : left(left), right(right) {}// 解释virtual int interpret() { return left->interpret() + right->interpret(); }private:Expression* left;Expression* right;
};// 减法表达式类
class SubExpression : public Expression
{
public:// 构造函数SubExpression(Expression* left, Expression* right) : left(left), right(right) {}// 解释virtual int interpret() { return left->interpret() - right->interpret(); }private:Expression* left;Expression* right;
};// 解释器类
class Interpreter
{
public:// 构造函数Interpreter(string exp) : expression(exp) {}// 解释int interpret() {stack<Expression*> s;// 遍历表达式字符for (int i = 0; i < expression.length(); i++) {if (isdigit(expression[i])) {// 识别数字int j = i;while (j < expression.length() && isdigit(expression[j])) {j++;}int num = stoi(expression.substr(i, j - i));s.push(new NumberExpression(num));i = j - 1;}else if (expression[i] == '+') {// 把左数提取出来Expression* left = s.top();s.pop();// 识别右数int j = i + 1;while (j < expression.length() && isdigit(expression[j])) {j++;}Expression* right = new NumberExpression(stoi(expression.substr(i + 1, j - (i + 1))));// 左数+右数的表达式放入栈中s.push(new AddExpression(left, right));i = j - 1;}else if (expression[i] == '-') {// 把左数提取出来Expression* left = s.top();s.pop();// 识别右数int j = i + 1;while (j < expression.length() && isdigit(expression[j])) {j++;}Expression* right = new NumberExpression(stoi(expression.substr(i + 1, j - (i + 1))));// 左数-右数的表达式放入栈中s.push(new SubExpression(left, right));i = j - 1;}}return s.top()->interpret();}private:string expression;
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include <unordered_map>
#include "Interpreter.h"using namespace std;int main()
{unordered_map<string, int> variables;string input;while (getline(cin, input)) {cout << "input:" << input << endl;Interpreter interpreter(input);variables[input] = interpreter.interpret();cout << "result:" << variables[input] << endl;}return 0;
}
程序结果如下。

上述实现的简易计算器,也是许多大学C/C++课程中的大作业,记得以前用MFC实现了一款计算器,开心了老半天哈哈,梦回大学。感兴趣的同学也可以试试复杂计算器,比如引入了括号还有各类运算符。
三、总结
我尽可能用较通俗的话语和直观的代码例程,来表述我对解释器模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解解释器模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
相关文章:
设计模式之解释器模式(C++)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、解释器模式是什么? 解释器模式是一种行为型的软件设计模式,定义了一个解释器,来解释给定语…...
基于MATLAB编程的粒子群算法优化BP神经网络风电功率预测,基于PSO-BP的风电功率预测
目录 摘要 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 粒子群算法的原理及步骤 基于粒子群算法改进优化BP神经网络的风电功率 matlab代码 代写下载链接:https://download.csdn.net/download/a…...
开心档之C++ 字符串
C 字符串 目录 C 字符串 C 风格字符串 实例 实例 C 中的 String 类 实例 C 提供了以下两种类型的字符串表示形式: C 风格字符串C 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 …...
Java Collection源码分析(JDk corretto 11)
文章目录 Collection 系列源码分析 (JDK Amazon corretto 11)Collection接口Iterable接口 子接口 QueueQueue的子接口 Deque双端队列 子接口ListArrayList 实现类序列化与反序列化(后续解决)获取Calss对象的方式 主要有三种:Arrays工具类System类 LinkedList实现类t…...
13种权重的计算方法
权重计算方法有很多种,不同的方法有不同的特点和适用情况。AHP层次分析法和熵值法在权重计算中属于比较常用的方法。除此之外,还有一些与权重计算相关的方法,今天一文总结了13种与权重计算相关的方法,大家可以对比选择使用。 一、…...
Devops和Gitops区别
一. 什么是devops DevOps 是一种开发(Dev)和运维(Ops)之间协作和沟通的文化、流程和工具的实践方法。它强调迭代、快速交付和持续集成/持续交付,旨在加速软件交付的速度、质量和稳定性。 DevOps 的核心目标是通过自动…...
拿下多家车企定点!4D毫米波雷达「域」系统首发出道
从1R、2R、3R到整车360感知方案,毫米波雷达的前装市场需求量依然保持着快速增长的态势。 高工智能汽车研究院监测数据显示,2022年中国市场(不含进出口)前装标配搭载ADAS毫米波雷达(前向后向盲区)交付1795.…...
【FATE联邦学习】FATE联邦学习使用GPU、指定cuda下标
问题 FATE框架1.x支持GPU训练吗? 寻找 先看了官网,搜官网,发现还是有的。 打开第一个后,里面可以用training param指定各个client的训练GPU,但是好像都是在large language model的。 而在文档中搜寻到的gpu…...
英文数字表达
1基数词 0 nought;zero;O 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 eight 9 nine 10 ten 11 eleven 12 twelve 13 thirteen 14 fourteen 15 fifteen 16 sixteen 17 seventeen 18 eighteen 19 nineteen 20 twenty21 twenty-one 22 twenty-two 23 twenty-three 30 th…...
第11届蓝桥杯省赛真题剖析-2020年6月21日Scratch编程初中级组
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第125讲。 第11届蓝桥杯省赛,这是2020年6月21日举办的省赛Scratch考试真题,原定于2020年3月7日…...
部署LVS-NAT群集实验
一、 实验准备 负载调度器:内网关 ens33:192.168.109.12,外网关 ens37:12.0.0.1外网 Web节点服务器1:192.168.109.13 Web节点服务器2:192.168.109.14 NFS服务器:192.168.109.11 客户端…...
对待工作的九个级别
只要是职场人,每天都要开展本职工作,有的人在职场上混得风生水起、平步青云,有的人却总是在原地踏步踏,总有一种怀才不遇的感叹,为什么呢?其实,差距就在于对待工作的态度上。 今天我们一起与各位…...
第四章 存储结构与管理硬盘
第四章 存储结构与管理硬盘 一、一切从“/”开始 1、Linux系统中常见的目录名称以及相应内容 目录名称应放置文件的内容/boot开机所需文件——内核、开机菜单以及所需配置文件等/dev以文件形式存放任何设备与接口/etc配置文件/home用户主目录/bin存放单用户模式下还可以操作…...
【腾讯云-2】极简搭建边缘集群
1 创建 流程和https://blog.csdn.net/qq_47058489/article/details/130347795差不多,可参考 查看基本信息: 创建边缘集群的过程中会初始化master,说明包含一个托管master节点 但是没有其他节点 2 开启节点远程登录 通过 SSH 的方式远…...
在springboot中给mybatis加拦截器
拦截器的作用就是我们可以拦截某些方法的调用,在目标方法前后加上我们自己逻辑 Mybatis拦截器设计的一个初衷是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。 mybatis 自定义拦截器 1、实现Interceptor 接口,并添加拦截注解 I…...
[oeasy]python0139_尝试捕获异常_ try_except_traceback
尝试捕获异常 回忆上次内容 变量相加 整型数字变量可以相加字符串变量也可以拼接 但是 字符串 和 整型数字整型数字 和 字符串不能相加 怎么办? 转格式int(“1”)str(2) 可是 如果输入的苹果数量是 字符串"abc" int(“abc”)会发生什么?&…...
树的刷题,嗝
今天忘记带本子了,就没有学习java了,于是一心刷题,好烦遇到了两个奇怪的题目,我没跟题解写的,但是我是没想到奇怪的样例. no.1 617. 合并二叉树 难度简单1221收藏分享切换为英文接收动态反馈 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中…...
举个栗子~Tableau 技巧(253):让筛选器只显示全部以及需要的类别
用户反馈了一个需求:我的业务数据有很多类别,但其实经常查看的只有几个,Tableau 筛选器能不能设置一下,只显示全部和经常查看的那几个类别? 这个是可以实现的!如下示例,数据类别有:…...
服务器温度过高告警
今天巡检一套rac环境,发现节点二上有Error字样,逐行看完细节是服务器温度过高导致的,半夜又没啥业务的,查看硬件也没任何告警,哎,某品牌的品控确实越来越烂,log一下 Mar 21 02:53:21 hydb1 ker…...
反垃圾邮件产品测试评价方法示意图
声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品测试评价方法 测试环境 反垃圾邮件产品的典型测试环境如图1所示。 图1 反垃圾邮件产品典型测试环境示意图 测试设…...
VMware虚拟机突然断网?别慌,试试这个NAT模式一键重置法(附主机WiFi适配器设置)
VMware虚拟机断网急救指南:NAT模式重置与主机适配器深度解析 从一次紧急调试说起 深夜11点23分,程序员老张正在虚拟机里调试一个即将上线的微服务接口。突然,git pull命令卡住不动,ping测试显示"Destination Host Unreachabl…...
Display Driver Uninstaller:彻底解决显卡驱动问题的专业工具指南
Display Driver Uninstaller:彻底解决显卡驱动问题的专业工具指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-u…...
终极指南:轻松解决TranslucentTB运行时依赖问题,让Windows任务栏完美透明化
终极指南:轻松解决TranslucentTB运行时依赖问题,让Windows任务栏完美透明化 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/Transluce…...
Redis对象类型与底层数据结构
一、Redis对象类型概述 1.1 Redis数据类型总览 Redis提供了丰富的数据类型,用于不同的业务场景:对象类型说明典型场景String字符串缓存、计数器、分布式锁List双向链表队列、消息队列、最新列表Hash哈希表存储对象、购物车Set无序集合好友关系、抽奖Zset…...
别再手动编译库了!一招永久设置Vivado全局Modelsim仿真环境
永久配置Vivado与Modelsim联调环境的终极方案 每次新建FPGA工程都要重新配置仿真工具路径和编译库文件?这种重复劳动不仅浪费时间,还容易因配置不一致导致仿真失败。本文将揭示一种被多数工程师忽略的"一劳永逸"配置方案,通过系统级…...
BetterDiscord Installer完全指南:如何一键安装和优化Discord插件
BetterDiscord Installer完全指南:如何一键安装和优化Discord插件 【免费下载链接】Installer A simple standalone program which automates the installation, removal and maintenance of BetterDiscord. 项目地址: https://gitcode.com/gh_mirrors/ins/Instal…...
港科大沈劭劼、谭平团队最新成果:开源280万全景数据集,实现零样本立体匹配
「一举攻克全景3D视觉两大瓶颈」 目录 01 行业痛点:数据匮乏与畸变失效的双重桎梏 1. 数据集稀缺,泛化能力受限 2. 球面畸变破坏单目先验一致性 02 核心突破:超大数据与航向对齐先验双驱动 1. 280万级合成数据集,打破数据壁…...
每月不到30元,在天翼云上搭建SK5多IP服务器的踩坑实录与成本优化指南
天翼云低成本搭建多IP代理服务器的实战指南与避坑手册 对于需要多IP操作的技术爱好者来说,如何在预算有限的情况下搭建稳定可靠的代理服务器一直是个难题。天翼云凭借其极具竞争力的价格和灵活的计费方式,成为许多精打细算用户的首选平台。本文将从一个实…...
复旦微FM33FR0xx开发板实战:从零构建低功耗电容触摸应用
1. 项目概述:从一块开发板说起最近在捣鼓智能家居的小玩意儿,想找个带触摸功能又够省电的MCU,正好看到了复旦微电子新出的FM33FR0xx系列开发套件。这板子到手玩了一阵,感觉挺有意思,它不单单是块核心板,还配…...
MySql学习杂谈 --- “连接“”
第一步:忘掉所有术语,记住一个生活场景 想象你要做一件事:查全班同学的考试成绩 表A(同学名单):张三,李四,王五,赵六 表B(考试成绩)࿱…...
