实战设计模式之解释器模式

概述

        作为一种行为设计模式,解释器模式提供了一种方法来定义语言的文法规则,并通过这些规则解析和处理特定类型的语言句子。简单来说,解释器模式允许我们定义一个代表某种语言中语法规则的对象结构,从而能够根据这些规则理解并处理语言中的表达式。

        表达式计算器是运用解释器模式的一个典型例子:想象一下,我们正在开发一个简单的数学表达式计算器,用户可以输入类似3 + (2 - 1)的表达式,并期望得到计算结果。在这种情况下,我们可以使用解释器模式来定义表达式的结构,并实现对这些表达式的解析和计算。解释器模式使得我们可以轻松地扩展新的运算符,或改变现有的运算逻辑,而无需修改已有的代码。

基本原理

        在软件项目中,我们有时需要处理        一些简单的语言或表达式,比如:SQL查询、正则表达式、数学表达式等。对于这些情况,我们可以使用解释器模式来构建一种机制,使得程序可以解析并执行这些表达式。

        解释器模式的核心思想是:为一种语言定义其文法表示,并定义一个或多个解释器,该解释器使用这种表示来解释语言中的句子。这里的“语言”可以是非常广泛的,从简单的数学表达式到复杂的编程语言都可以适用。解释器模式主要由以下五个核心组件构成。

        1、抽象表达式。声明一个抽象的解释操作,这个接口为所有具体表达式所遵循。

        2、终结符表达式。实现了与文法中的终结符相关的解释操作,每个句子中的终结符都需要该类的一个实例。

        3、非终结符表达式。文法中的每一条规则,都至少需要一个具体的非终结符表达式类。每个类都实现了对子表达式的解释,并存储了对下一层表达式对象的引用。

        4、上下文。包含了解释器之外的一些全局信息。

        5、客户端。构建表示该文法定义的语言中一个特定的句子的抽象语法树。抽象语法树由非终结符表达式和终结符表达式的对象构成,然后初始化变量并在抽象语法树中启动解释操作。

        基于上面的核心组件,解释器模式的实现主要有以下四个步骤。

        1、定义文法规则。首先,明确想要解释的语言的文法规则。比如:如果要解释简单的算术表达式,你的文法规则可能包括加法、减法以及数字等。

        2、创建抽象表达式接口。创建一个抽象基类或接口,其中定义了一个类似Interpret的抽象方法。所有的表达式,无论是终结符还是非终结符,都将实现这个接口。

        3、实现终结符表达式。对于文法中的每一个终结符(比如:数字),创建一个具体的类实现接口,这个类通常不需要其他表达式的帮助就能完成解释工作。

        4、实现非终结符表达式。对于文法中的每一个非终结符(比如:加法、减法等运算符),创建一个具体的类实现接口。这个类会包含对其他表达式的引用,并通过递归调用它们的Interpret方法来完成解释工作。

        5、构建抽象语法树。根据输入的句子,构造出代表该句子结构的抽象语法树。这棵树由非终结符表达式和终结符表达式的对象构成。

        6、使用上下文执行解释操作。通过调用抽象语法树根节点的Interpret方法,并传入上下文对象来开始解释过程。其中,上下文对象可以用来存储全局状态或者参数。

实战解析

        在下面的实战代码中,我们使用解释器模式模拟了表达式计算器的实现。

        首先,我们定义了抽象基类CExpression。它声明了一个纯虚函数Interpret,用于后续所有具体表达式的解释操作。

        接着,我们定义了两个具体的表达式类。CNumberExpression作为终结符表达式表示数字,CAddExpression和CSubtractExpression作为非终结符表达式分别表示加法和减法操作。

        最后,在main函数中,通过创建一系列对象来构建表达式的抽象语法树。这里构建的具体表达式是60 + (9 - 3),再调用最顶层表达式的Interpret方法来计算整个表达式的值,并输出结果。

#include <iostream>using namespace std;// 抽象表达式
class CExpression
{
public:virtual int Interpret() const = 0;virtual ~CExpression() {}
};// 终结符表达式:数字
class CNumberExpression : public CExpression
{
public:CNumberExpression(int nValue) : m_nValue(nValue) {}int Interpret() const override{return m_nValue;}private:int m_nValue;
};// 非终结符表达式:加法
class CAddExpression : public CExpression
{
public:CAddExpression(CExpression *pLeft, CExpression *pRight): m_pLeft(pLeft), m_pRight(pRight) {}int Interpret() const override{return m_pLeft->Interpret() + m_pRight->Interpret();}private:CExpression *m_pLeft;CExpression *m_pRight;
};// 非终结符表达式:减法
class CSubtractExpression : public CExpression
{
public:CSubtractExpression(CExpression *pLeft, CExpression *pRight): m_pLeft(pLeft), m_pRight(pRight) {}int Interpret() const override{return m_pLeft->Interpret() - m_pRight->Interpret();}private:CExpression *m_pLeft;CExpression *m_pRight;
};int main()
{// 创建子表达式: (9 - 3)CNumberExpression *pNum1 = new CNumberExpression(9);CNumberExpression *pNum2 = new CNumberExpression(3);CSubtractExpression *pSub = new CSubtractExpression(pNum1, pNum2);// 创建主表达式: 60 + (9 - 3)CNumberExpression *pNum3 = new CNumberExpression(60);CAddExpression *pResult = new CAddExpression(pNum3, pSub);// 执行解释操作int nResult = pResult->Interpret();// 输出结果cout << "Result: " << nResult << endl;delete pResult;delete pNum3;delete pSub;delete pNum2;delete pNum1;return 0;
}

总结

        通过将每条语法规则映射到一个具体的类,解释器模式可以将复杂的解释逻辑分解为多个独立的部分,每个部分负责处理特定类型的语法。这样不仅使代码更易读,也更容易维护。新的语法或表达式可以通过添加新的类来实现,而不需要修改现有的代码。这使得系统更加灵活,能够适应不断变化的需求。

        但当面对复杂的语言或大量数据时,解释器模式可能会导致性能瓶颈。这是因为,每次解释都需要遍历整个抽象语法树,且通常涉及大量的对象创建和递归调用。随着语言文法变得越来越复杂,相应的抽象语法树也会变得庞大且难以管理。特别是当文法规则频繁变动时,维护成本会显著增加。

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

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

相关文章

物联网边缘计算网关是什么?

在物联网的浩瀚架构中&#xff0c;边缘计算网关宛如一位坚毅的前沿哨兵&#xff0c;默默守护着数据处理与传输的关键防线&#xff0c;为整个物联网系统的高效运转发挥着不可或缺的作用。 一、边缘计算网关的定义与基本功能 边缘计算网关是一种智能设备&#xff0c;它被部署在…

计算机视觉算法实战——障碍物识别(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​ ​​​​​​ ​ ​ 1. 引言 计算机视觉是人工智能领域的一个重要分支&#xff0c;旨在通过计算机模拟人类的视觉系统&#xff0c;从…

Win11锁屏后显示“天气、市场、广告”如何取消显示

关闭方法&#xff1a;设置>个性化>锁屏界面>锁屏界面状态>"无"。 方法一&#xff1a;通过“个性化”设置 打开“设置”应用&#xff1a; 点击屏幕左下角的“开始”按钮&#xff08;Windows 图标&#xff09;。点击齿轮状的“设置”图标。或者按下 Win I…

10天速通强化学习-008

TRPO 思考-TRPO-在线策略-给定信任区域防止更新不稳定 Actor-Critic网络随着网络深度的增加&#xff0c;步长太长&#xff0c;梯度更新会变差。改变方法-增加信任区域。(trust region policy optimization)-TRPO算法&#xff1a; 核心思想&#xff1a; 是在每次迭代中&…

整合百款经典街机游戏的模拟器介绍

对于80、90后而言&#xff0c;街机游戏承载着童年的欢乐记忆。今天要给大家介绍一款超棒的软件——「MXui街机厅经典游戏101款」&#xff0c;它能带你重回那段热血沸腾的街机时光。 「MXui街机厅经典游戏101款」是一款绿色免安装的街机模拟器&#xff0c;体积约1.39G。无需繁琐…

springboot第三站(1) web开发引入

目录 1.简介 2.SpringBoot对静态资源的映射规则 3.模版引擎 1.简介 使用SpringBoot&#xff1b; 1&#xff09;、创建SpringBoot应用&#xff0c;选中我们需要的模块&#xff1b; 2&#xff09;、SpringBoot已经默认将这些场景配置好了&#xff0c;只需要在配置文件中指定…

12-二叉树-二叉树高度(给定前序和中序确定二叉树)

题目 来源 23. 二叉树的高度 思路 其实跟09那篇很像&#xff0c;反正核心就是要通过前序和中序来建树&#xff0c;只不过现在多了一个返回值&#xff1b;因为建树的时候&#xff0c;其实左子树和右子树的深度就可以知道。其余详见代码。 代码 /* 前序遍历根左右,中序&…

PSI5接口

文章目录 前言PSI5接口简介操作模式命名规则异步操作模式&#xff08;PSI5-A&#xff09;同步操作模式&#xff08;PSI5-P&#xff09; 传感器->ECU物理层&#xff08;位编码&#xff09;数据链路层数据帧帧格式串行消息帧10bits 传感器帧定义超10bits传感器帧定义 ECU->…

垃圾处理全流程监管平台

在当前城市化进程中&#xff0c;垃圾处理已成为城市管理的重要课题。随着技术的发展&#xff0c;垃圾处理全流程监管平台的建设显得尤为重要。该平台能够实现垃圾从产生、收集、运输到最终处理的全流程监管&#xff0c;提高垃圾处理效率&#xff0c;促进资源回收利用&#xff0…

【Linux编程】IPC之消息队列从踩坑到实战:核心原理、实战案例与C++封装详解(含完整代码)

一、消息队列基础概念 消息队列是Linux系统提供的一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;具有以下特点&#xff1a; 消息以链表形式存放在内核中每个消息包含类型标识&#xff08;mtype&#xff09;支持多生产者/多消费者模式消息总长度受限于系统配置&a…

Unity 项目工程结构目录

1. Unity.VisualScripting.Core 作用: Visual Scripting 的核心模块&#xff0c;提供了可视化编程的基础功能&#xff08;前身为 Bolt&#xff09;。它允许开发者通过节点图创建游戏逻辑&#xff0c;而无需编写代码。 典型用途: 非程序员快速构建原型&#xff0c;或简化…

从pdf提取文本数据的c/cpp库(非OCR)

Aspose.PDF for C 商业付费版&#xff0c;无源码。 功能强大&#xff0c;支持多种PDF操作。 对应的官方示例代码&#xff1a;Aspose.PDF-for-C Spire.PDF for C 商业付费版 对应的官方示例代码&#xff1a;Spire.PDF-for-C- PDFTron SDK 商业付费版 PoDoFo 开源 当前版本…

【Linux操作系统——学习笔记二】Linux简单导航命令操作

一、前言 学习Linux&#xff0c;本质上是学习在命令行下熟练使用Linux的各类命令。 命令行&#xff1a;是一种通过输入命令和参数与计算机系统进行交互的方式&#xff0c;可以使用各种字符化命令对系统发出操作指令&#xff0c;打开Linux终端&#xff0c;进入命令行界面。 …

赛逸展2025创新模式,以科技创新奖赋能展位战略价值

CES Asia2025第七届亚洲消费电子技术贸易展&#xff08;赛逸展&#xff09;主办方负责人提出的创新理念&#xff0c;为展会的战略价值注入了新活力&#xff1a;“我们不是在卖展位&#xff0c;而是在分发政策红利入场券——企业每平方米的展位投入&#xff0c;都可能通过科技创…

深度革命:ResNet 如何用 “残差连接“ 颠覆深度学习

一文快速了解 ResNet创新点 在深度学习的历史长河中&#xff0c;2015年或许是最具突破性的一年。这一年&#xff0c;微软亚洲研究院的何恺明团队带着名为ResNet&#xff08;残差网络&#xff09;的模型横空出世&#xff0c;在ImageNet图像分类竞赛中以3.57%的错误率夺冠&#…

将Django连接到mysql

将Django连接到mysql 文章目录 将Django连接到mysql一.按照我的文章 在Django模型中的Mysql安装 此篇 的步骤完成mysql的基础配置二.Django配置 一.按照我的文章 ‘在Django模型中的Mysql安装’ 此篇 的步骤完成mysql的基础配置 基础配置具体内容 1.打开PowerShell 安装mysql的…

Pycatia自动化开发:智能焊点生成与数据管理一体化解决方案

引言&#xff1a;机械设计自动化的新范式 在汽车白车身、航空结构件等复杂装配体设计中&#xff0c;焊点定位精度直接影响产品性能和制造可行性。传统CAD软件操作模式存在两大痛点&#xff1a;1&#xff09;重复性点创建操作效率低下&#xff1b;2&#xff09;坐标数据缺乏结构…

《Python实战进阶》No26: CI/CD 流水线:GitHub Actions 与 Jenkins 集成

No26: CI/CD 流水线&#xff1a;GitHub Actions 与 Jenkins 集成 摘要 持续集成&#xff08;CI&#xff09;和持续部署&#xff08;CD&#xff09;是现代软件开发中不可或缺的实践&#xff0c;能够显著提升开发效率、减少错误并加速交付流程。本文将探讨如何利用 GitHub Actio…

【css酷炫效果】纯CSS实现3D翻转卡片动画

【css酷炫效果】纯CSS实现3D翻转卡片动画 缘创作背景html结构css样式完整代码效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90490472 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚看到csdn出活动了&am…

大数据学习(72)-zookeeper选举机制

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…