【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

解释

在上述示例中,使用解释器模式实现了一个简单的数学表达式解析器。程序首先将输入的字符串表达式解析成为抽象语法树,并通过遍历和解释节点来执行计算操作。最后输出计算的结果。

结论

解释器模式可以用于处理复杂的业务规则和语言解析。它可以将复杂的业务逻辑分解为一系列的简单表达式进行处理,从而提高代码的可读性和维护性。

应用场景

解释器模式适用于以下情况:

  • 当业务逻辑较为复杂,且可以被分解为一系列简单表达式时。
  • 当需要构建一种特定领域的语言或解析器时。
  • 当需要灵活地支持变化的业务规则或语法规则时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/99212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用 HTTP 提交数据,基本就这 5 种方式

网页开发中&#xff0c;向服务端提交数据是一个基本功能&#xff0c;工作中会大量用 xhr/fetch 的 api 或者 axios 这种封装了一层的库来做。 可能大家都写过很多 http/https 相关的代码&#xff0c;但是又没有梳理下它们有哪几种呢&#xff1f; 其实通过 http/https 向服务端…

VBox启动失败、Genymotion启动失败、Vagrant迁移

VBox启动失败、Genymotion启动失败、Vagrant迁移 2023.10.9 最新版本vbox7.0.10、Genymotion3.5.0 Vbox启动失败 1、查看日志 Error -610 in supR3HardenedMainInitRuntime! (enmWhat4) Failed to locate ‘vcruntime140.dll’ 日志信息查看方法->找到虚拟机所在位置->…

对于L1正则化和L2正则化的理解

在DL中&#xff0c;L1和L2正则化经常被使用到&#xff0c;因为大于1L的正则化都是凸优化的问题&#xff0c;是个简单问题&#xff0c;可以被解决。 首先说正则的意义&#xff1a; 一切可以缓解过拟合的方法&#xff0c;都可以被叫做正则化 我最开始理解正则化的时候就是看lh…

【Bond随你温故Azure Architecture】之HADR篇

上次复盘数据保护策略还是在《数据需要找回怎么办&#xff1f;我们如何选择正确的恢复/退回方式&#xff1f;》探讨了在application&DB层面上&#xff0c;不同level的数据保护有不同策略。而它也恰好是今天HA&DR版图的一角&#xff08;RDBMS部分&#xff09;&#xff0…

CI/CD工具中的CI和CD的含义

CI/CD工具中的CI和CD的含义&#xff1f; CI/CD 是现代软件开发方法中广泛使用的一种方法。其中&#xff0c;CI 代表持续集成&#xff08;Continuous Integration&#xff09;&#xff0c;CD 则有两层含义&#xff0c;一是持续交付&#xff08;Continuous Delivery&#xff09;…

.net framework中webapi使用swagger进行接口文档展示

第一步&#xff1a;在nuget程序包管理中搜索“Swashbuckle”包&#xff0c;然后进行安装&#xff08;注&#xff1a;如果是.net core api请安装Sawshbuckle aspnetcore&#xff09;。 第二步&#xff1a;打开项目App_Start文件夹&#xff0c;修改SwaggerConfig.cs配置文件 我这…

mp4视频太大怎么压缩变小?

mp4视频太大怎么压缩变小&#xff1f;确实&#xff0c;很多培训和教学都转向了线上模式&#xff0c;这使得我们需要下载或分享大量的在线教学视频。然而&#xff0c;由于MP4视频文件通常较大&#xff0c;可能会遇到无法打开或发送的问题。为了解决这个问题&#xff0c;我们可以…

聊聊分布式架构02——Http到Https

目录 HTTP通信协议 请求报文 响应报文 持久连接 状态管理 HTTPS通信协议 安全的HTTPS HTTP到HTTPS的演变 对称加密 非对称加密 混合加密机制 证书机构 SSL到底是什么 HTTPS是身披SSL外壳的HTTP HTTP通信协议 一次HTTP请求的通信流程&#xff1a;客户端浏览器通过…

【Linux升级之路】7_进程信号

目录 一、【Linux初阶】信号入门 | 信号基本概念信号产生核心转储二、【Linux初阶】信号入门2 | 信号阻塞、捕捉、保存 一、【Linux初阶】信号入门 | 信号基本概念信号产生核心转储 链接&#xff1a; 【Linux初阶】信号入门 | 信号基本概念信号产生核心转储 二、【Linux初阶】…

【数据结构-字符串 三】【字符串转换】字符串解码

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【字符串转换】&#xff0c;使用【字符串】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

RPC分布式网络通信框架项目

文章目录 对比单机聊天服务器、集群聊天服务器以及分布式聊天服务器RPC通信原理使用Protobuf做数据的序列化&#xff0c;相比较于json&#xff0c;有哪些优点&#xff1f;环境配置使用项目代码工程目录vscode远程开发Linux项目muduo网络库编程示例CMake构建项目集成编译环境Lin…

【计算机网络黑皮书】传输层

【事先声明】 这是对于中科大的计算机网络的网课的学习笔记&#xff0c;感谢郑烇老师的无偿分享 书籍是《计算机网络&#xff08;自顶向下方法 第6版&#xff09;》 需要的可以私信我&#xff0c;无偿分享&#xff0c;课程简介下也有 课程链接 目录 传输服务与协议网络层与传输…

常见排序算法Java版(待续)

冒泡排序O(n^2) public class Main {public static void main(String[] args) {Random random new Random();int[] nums new int[]{random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100)};for (i…

英特尔参与 CentOS Stream 项目

导读红帽官方发布公告欢迎英特尔参与进 CentOS Stream 项目&#xff0c;并表示 “这一举措不仅进一步深化了我们长期的合作关系&#xff0c;也构建在英特尔已经在 Fedora 项目中积极贡献的基础之上。” 目前&#xff0c;CentOS Stream 共包括以下特别兴趣小组&#xff08;SIG&a…

汽车冲压车间的RFID技术设计解决方案

一、RFID技术的基本原理 RFID技术是一种利用非接触式自动识别的技术&#xff0c;通过将RFID标签放置在被识别物品上&#xff0c;并使用RFID读写器对标签进行扫描和识别&#xff0c;实现对物品的自动识别和追踪。RFID标签分为被动式和主动式两种。被动式标签无内置电源&#xf…

23.3 Bootstrap 框架4

1. 轮播 1.1 轮播样式 在Bootstrap 5中, 创建轮播(Carousel)的相关类名及其介绍: * 1. carousel: 轮播容器的类名, 用于标识一个轮播组件. * 2. slide: 切换图片的过渡和动画效果. * 3. carousel-inner: 轮播项容器的类名, 用于包含轮播项(轮播图底下椭圆点, 轮播的过程可以显…

HTTP协议的请求协议和响应协议的组成,HTTP常见的状态信息

HTTP协议 什么是协议 协议实际上是某些人或组织提前制定好的一套规范,大家只要都按照这个规范来就可以做到沟通无障碍 HTTP协议是W3C(万维网联盟组织)制定的一种超文本传输通信协议(发送消息的模板和数据的格式),除了传送字符串,还有声音、视频、图片等流媒体等超文本信息 …

ctfshow-web11(session绕过)

php代码审计&#xff1a; function replaceSpecialChar($strParam){$regex "/(select|from|where|join|sleep|and|\s|union|,)/i";return preg_replace($regex,"",$strParam);} 首先定义了一个函数&#xff0c;主要是使用preg_replace函数对我们提交的内…

SpringBoot的创建和使用

优点 快速添加依赖&#xff1b; 内置web容器&#xff1b; 自动装配&#xff1b; idea创建 创建maven项目&#xff08;配置&#xff09; 一定要选择2.x版本的Spring Boot 介绍目录 (有这个注解的SpringBootApplication就是启动类) 删除文件 尝试去运行带有SpringBootApplica…

面向对象设计-UML六种箭头含义

目录 UML概述UML语义UML表示法 六种常用关系标识方法泛化实现依赖关联聚合组合 本文参考文章 https://blog.csdn.net/qq_25091281/article/details/123801862 UML概述 UML (Unified Modeling Language)为面向对象软件设计提供统一的、标准的、可视化的建模语言。适用于描述以…