【C++设计模式之解释器模式:行为型】分析及示例
简介
解释器模式(Interpreter Pattern)是一种行为型设计模式,它提供了一种解决问题的方法,通过定义语言的文法规则,解释并执行特定的语言表达式。
解释器模式通过使用表达式和解释器,将文法规则中的句子逐个解释执行。它将一些复杂的业务逻辑分解为一系列的简单表达式,通过解析和执行这些表达式来实现业务逻辑的处理。
描述
解释器模式通常用于处理某种特定领域的语言或规则。它将待解析的句子转换为抽象语法树,并按照语法规则逐个解析节点。每个节点都可以表示一个终结符或非终结符,并提供相应的解释方法。
原理
解释器模式的核心原理是将句子解析成为抽象语法树,然后通过遍历和解释节点来执行语义操作。解释器模式通常包含以下角色:
- 抽象表达式(Abstract Expression):定义了解释器的抽象接口,包含解释方法 interpret()。
- 终结符表达式(Terminal Expression):表示句子中的终结符(如变量、常量等),实现了解释方法 interpret()。
- 非终结符表达式(Nonterminal Expression):表示句子中的非终结符(如加法、减法等运算),定义了解释方法 interpret()。
类图

Context:环境角色(上下文),含有每个解释器所需的一些数据或全局的一些信息。
AbstractExpression:抽象表达式类,声明了抽象的解释操作,所有解释器类都继承或实现该类。
TerminalExpression:终结符表达式类,是AbstractExpression的子类,实现了文法中有关终结符相关的解释操作。
NonTerminalExpression:非终结符表达式,AbstractExpression的子类,该类的功能与终结表达式类相反,文法中所有非终结符由该类进行解释。
Client:客户端测试类。
示例
假设我们需要实现一个简单的数学表达式解析器,可以计算表达式的值。表达式可以包含整数、加法和减法操作。
在下面的示例中,我们定义了抽象表达式类 Expression 和具体的终结符表达式类 IntegerExpression,以及具体的非终结符表达式类 AddExpression 和 SubtractExpression。程序通过解析句子中的各个表达式,并执行相应的操作。
#include <iostream>
#include <string>
#include <stack>// 抽象表达式类
class Expression {
public:virtual int interpret() 0;
};// 终结符表达式类
class IntegerExpression : public Expression {
private:int value;public:IntegerExpression(int value) : value(value) {}int interpret() {return value;}
};// 非终结符表达式类
class AddExpression : public Expression {
private:Expression* left;Expression* right;public:AddExpression(Expression* left, Expression* right): left(left), right(right) {}int interpret() {return left->interpret() + right->interpret();}
};class Subtract : public Expression {
privateExpression* left;Expression* right;public:SubtractExpression(Expression* left, Expression* right): left(left), right(right) {}int interpret() {return left->interpret() - right->interpret();}
};// 解析器
class Parser {
public:static Expression* parse(const std::string& input) {std::stack<Expression*> expressionStack;int pos = 0;while (pos < input.size()) {if (isdigit(input[pos])) {int value = 0;while (pos < input.size() && isdigit(input[pos])) {value = value * 10 + (input[pos] - 0);pos++;}expressionStack.push(new IntegerExpression(value));} else if (input[pos] == '+') {Expression* right = expressionStack.top();expressionStack.pop();Expression* left = expressionStack.top();expressionStack.pop();expressionStack.push(new AddExpression(left, right));pos++;} else if (input[pos] == '-') {Expression* right = expressionStack.top();expressionStack.pop();Expression* left = expressionStack.top();expressionStack.pop();expressionStack.push(new SubtractExpression(left, right));pos++;} else {pos++;}}return expressionStack.top();}
};int main() {std::string input = "5+2-1";Expression* expression = Parser::parse(input);int result = expression->interpret();std::cout << "Result: " << result << std::endl;delete expression;return 0;
}
输出结果
Result: 6
解释
在上述示例中,使用解释器模式实现了一个简单的数学表达式解析器。程序首先将输入的字符串表达式解析成为抽象语法树,并通过遍历和解释节点来执行计算操作。最后输出计算的结果。
结论
解释器模式可以用于处理复杂的业务规则和语言解析。它可以将复杂的业务逻辑分解为一系列的简单表达式进行处理,从而提高代码的可读性和维护性。
应用场景
解释器模式适用于以下情况:
- 当业务逻辑较为复杂,且可以被分解为一系列简单表达式时。
- 当需要构建一种特定领域的语言或解析器时。
- 当需要灵活地支持变化的业务规则或语法规则时。
相关文章:
【C++设计模式之解释器模式:行为型】分析及示例
简介 解释器模式(Interpreter Pattern)是一种行为型设计模式,它提供了一种解决问题的方法,通过定义语言的文法规则,解释并执行特定的语言表达式。 解释器模式通过使用表达式和解释器,将文法规则中的句子逐…...
35 WEB漏洞-逻辑越权之找回机制及接口安全
目录 找回重置机制接口调用乱用演示案例绑定手机验证码逻辑-Rep状态值篡改-实例某APP短信轰炸接口乱用-实例接口调用发包 文章分享:https://www.cnblogs.com/zhengna/p/15655691.html 有支付接口、短信发送接口,邮箱的发送接口等等,在接口这…...
黑豹程序员-架构师学习路线图-百科:JSON替代XML
文章目录 1、数据交换之王2、XML的起源3、JSON诞生4、什么是JSON 1、数据交换之王 最早多个软件之间使用txt进行信息交互,缺点:纯文本,无法了解其结构;之后使用信令,如:电话的信令(拨号、接听、…...
考研人考研魂——英语单词篇(20231009)
下一站,上岸 consoleconsistentconsistconstituteconstitutionconstituentconstructdistinctdistinguishdistinctionconstantconstrainfruitfulfulfillfundfunctionfrustrateevidencefundamentalevilevidentenvironmententertainmententertainenterprisemonotonousm…...
【数据结构】HashSet的底层数据结构
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 HashSet 一、 HashSet 集合的底层数据结构二…...
数据结构与算法(七)--使用链表实现栈
一、前言 之前我们已经学习了链表的所有操作及其时间复杂度分析,我们可以了解到对于链表头的相关操作基本都是O(1)的,例如链表头增加、删除元素,查询元素等等。那我们其实有一个数据结构其实可以完美利用到这些操作的特点,都是在…...
分布式事务详解
摘要 分布式事务主要包括2pc、3pc、消息事务。 2pc指两阶段提交: 第一阶段是准备阶段:所有事务参与者检查执行能力并锁定对应资源,准备完成后将状态告知协调者。第二集段是提交状态:事务参与者全部准备好后,协调者发…...
车载通信架构 —— DDS协议介绍
车载通信架构 —— DDS协议介绍 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和…...
nginx根据不同的客户端设备进行转发请求——筑梦之路
这里主要介绍七层负载方式实现。 环境说明: pc端 web-1 苹果ios端 web-2 安卓Android端 web-3 负载均衡 web-lb 配置示例: pc端: server {listen 9000; #监听9000server_name pc.xxx.com;charset utf-8;location / {root /…...
增强LLM:使用搜索引擎缓解大模型幻觉问题
论文题目:FRESHLLMS:REFRESHING LARGE LANGUAGE MODELS WITH SEARCH ENGINE AUGMENTATION 论文地址:https://arxiv.org/pdf/2310.03214.pdf 论文由Google、University of Massachusetts Amherst、OpenAI联合发布。 大部分大语言模型只会训练一次&#…...
WPF向Avalonia迁移(一、一些通用迁移项目)
通用变更 WPF:Visibility 其他参考文档 WPF: <TextBlock Visibility"Visible"/><TextBlock Visibility"Collapsed"/><TextBlock Visibility"Hidden"/>Avalonia : <TextBlock IsVisib…...
lua学习笔记
单行注释: 多行注释: 命名: Lua不支持下划线大写字母,比如:_ABC 但支持:_abc 关键字: 全局变量: 直接变量名 内容就是全局 局部变量: 加上local即可 nil࿱…...
修改 ModelScope 默认缓存路径
修改 ModelScope 默认缓存路径 设置 MODELSCOPE_CACHE 和 MODELSCOPE_MODULES_CACHE 两个环境变量。 export MODELSCOPE_CACHE<your_favourite_path>/hub export MODELSCOPE_MODULES_CACHE<your_favourite_path>/modelscope_modules完结!...
【ES实战】索引别名的使用说明
索引别名 文章目录 索引别名带有过滤器的别名RoutingWrite Index REST单一添加一个别名示例: 索引创建是增加别名删除别名检索现有别名示例: 索引别名可以通过API的方式进行操作一个索引别名可以映射到一个或一个以上的索引索引名和索引别名不能重复,在集群中都是唯…...
QT信号与槽机制 和 常用控件介绍
QT信号与槽机制 1、信号(signal): 所谓信号槽 (观察者模式)信号本质是事件。信号展现方式就是函数。当某一个事件发生之后,则发出一个信号(signal). 2、槽(slot): 就是对信号响应的函数,槽就是一个函数。槽函数与普通函数区别槽函数可以与一个信号关联&…...
【css-banner图片自适应】
<picture><source media"(max-width: 480px)" srcset"图片地址"><source media"(min-width: 481px)" srcset"图片地址"><img src"图片地址" id"homebanner"></picture>img{height:…...
【k8s管理操作】
k8s管理操作 一、k8s管理操作1.陈述式资源管理2.声明式资源管理 二、k8s基础信息常看(命令)增删改查项目的生命周期:创建-->发布-->更新-->回滚-->删除 headless clusterIP 无头模式 金丝雀发布(Canary Release&#…...
【java基础学习】之DOS命令
#java基础学习 1.常用的DOS命令: dir:列出当前目录下的文件以及文件夹 md: 创建目录 rd:删除目录cd:进入指定目录 cd.. :退回到上级目录 cd\ : 退回到根目录 del:删除文件 exit:退出dos命令行 1.dir:列出当前目录下的文件以及文件夹 2.md: 创建目录 …...
学习记录——StyleGAN2+SA-UNet
SA-UNet for Retinal Vessel improvment using StyleGAN2 作者提出了一种改进视网膜图像分割的方法,通过创建图像及其相应的分割地图来实现。作者的解决方案包括使用DRIVE数据集1对StylGAN2进行训练,并使用目前在分割DRIVE图像方面取得最先进结果的SA-UNet模型对新合成的图像…...
JVM222
文章目录 JVM222运行时数据区的内部结构线程程序计数器(PC寄存器)虚拟机栈 JVM222 运行时数据区的内部结构 概述 本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载器加载完成后的阶段,如下图: …...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
