设计模式26-解析器模式

设计模式26-解析器模式

  • 动机
  • 定义与结构
    • 定义
    • 结构
  • C++代码推导
    • 代码说明
  • 优缺点
  • 应用
  • 总结

动机

  • 在软件构建过程中,如果某一特定领域的问题比较复杂,类似结构会不断重复的出现。如果使用普通的编程方式来实现,将面临非常频繁的变化。

  • 在这种情况下,将特定领域的问题表达为某种语法规则下的句子。然后构建一个解释器来解释这样的句子。从而达到解决问题的目的。

  • 解析器模式(Interpreter Pattern)主要用于设计一个语言的解释器,该语言可能是简单的命令语言、表达式语言、或某种配置语言。动机源于这样一个需求:在某些应用程序中,可能会涉及到对特定领域语言(DSL)的解释或执行。为了避免重复编写这些语言的解释代码,并使代码易于扩展和维护,解析器模式提供了一种可行的解决方案。

  • 解析器模式通过为语言的每一个表达式(或符号)定义一个类来实现解释操作。这些类通过组合来构建复杂的表达式,并且这些表达式可以在运行时被解释和执行。使用解析器模式可以让你轻松地为新的表达式添加支持,而无需修改现有代码。

定义与结构

定义

解析器模式是一种行为设计模式,它定义了一个语言的语法表示,并实现一个解释器来处理该语言的句子。解析器模式将表达式解析为抽象语法树(AST),然后通过遍历语法树来执行或评估表达式。

结构

在这里插入图片描述

这张图片展示了解析器模式(Interpreter Pattern)的类结构。解析器模式是一种行为设计模式,它定义了一个表达式的接口,用来解释一个特定的上下文中的表达式。这种模式被用于构建解释器,这些解释器用于分析字符串、数学表达式或任何其他需要解释的语法。

以下是类图中各部分的详细解释:

  1. Context 类

    • Context 通常是解析过程中的上下文环境。它包含了所有与解释操作相关的全局信息。在图中的类结构中,Context 被错误地描述为 TerminalExpressionNonterminalExpression 的基类,这在标准的解析器模式实现中是不常见的。实际上,Context 应该是独立于表达式类型的,用于在解释过程中传递数据。
  2. Expression 接口

    • 虽然图中没有明确显示,但在解析器模式中,通常会有一个 Expression 接口(或抽象类),它定义了 Interpret(Context) 方法。这个方法用于对表达式进行解释,并根据当前上下文环境返回结果。TerminalExpressionNonterminalExpression 通常会实现这个接口。
  3. TerminalExpression 类

    • TerminalExpression 是实现了 Expression 接口的类之一,用于表示解析树中的叶子节点。这些节点是表达式的最基本单元,例如字面量值(如数字、字符串等),它们不包含其他表达式。TerminalExpression 类的 Interpret(Context) 方法将直接返回该表达式的结果,而不需要进一步解析。
  4. NonterminalExpression 类

    • NonterminalExpression 也是实现了 Expression 接口的类,但它代表了解析树中的非叶子节点。这些节点通常包含了一个或多个其他表达式(子节点),并定义了如何将这些子表达式的解释结果组合起来形成最终的结果。NonterminalExpressionInterpret(Context) 方法会递归地调用其子节点的 Interpret 方法,并根据需要处理这些结果。
  5. Client 类

    • Client 类是解析器模式的使用者,它构建了一个表达式树(由 TerminalExpressionNonterminalExpression 实例组成),并通过调用根节点的 Interpret(Context) 方法来启动解释过程。Client 类负责设置解析所需的初始上下文,并处理解释结果。

C++代码推导

以下是一个简单的解析器模式示例,它实现了一个基本的数学表达式解释器,该解释器支持加法和减法操作。

#include <iostream>
#include <string>
#include <map>
#include <memory>// 上下文类,包含变量的值
class Context {
public:void setVariable(const std::string& name, int value) {variables[name] = value;}int getVariable(const std::string& name) const {auto it = variables.find(name);if (it != variables.end()) {return it->second;}return 0; // 默认返回0}private:std::map<std::string, int> variables;
};// 抽象表达式类
class Expression {
public:virtual ~Expression() = default;virtual int interpret(const Context& context) const = 0;
};// 终结符表达式类,用于表示变量
class VariableExpression : public Expression {
public:VariableExpression(const std::string& name) : name_(name) {}int interpret(const Context& context) const override {return context.getVariable(name_);}private:std::string name_;
};// 终结符表达式类,用于表示数字常量
class NumberExpression : public Expression {
public:NumberExpression(int value) : value_(value) {}int interpret(const Context& context) const override {return value_;}private:int value_;
};// 非终结符表达式类,用于表示加法
class AddExpression : public Expression {
public:AddExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {}int interpret(const Context& context) const override {return left_->interpret(context) + right_->interpret(context);}private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;
};// 非终结符表达式类,用于表示减法
class SubtractExpression : public Expression {
public:SubtractExpression(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right): left_(std::move(left)), right_(std::move(right)) {}int interpret(const Context& context) const override {return left_->interpret(context) - right_->interpret(context);}private:std::unique_ptr<Expression> left_;std::unique_ptr<Expression> right_;
};int main() {Context context;context.setVariable("x", 10);context.setVariable("y", 20);// 表达式 x + y - 5auto expression = std::make_unique<SubtractExpression>(std::make_unique<AddExpression>(std::make_unique<VariableExpression>("x"),std::make_unique<VariableExpression>("y")),std::make_unique<NumberExpression>(5));std::cout << "Result: " << expression->interpret(context) << std::endl; // 输出 25return 0;
}

代码说明

  1. Context(上下文):存储变量及其对应的值,提供获取变量值的接口。
  2. Expression(抽象表达式):定义了一个interpret方法,用于解释或计算表达式的值。
  3. VariableExpression(终结符表达式):表示变量,根据上下文返回变量的值。
  4. NumberExpression(终结符表达式):表示数字常量,返回常量值。
  5. AddExpression(非终结符表达式):实现加法操作。
  6. SubtractExpression(非终结符表达式):实现减法操作。
  7. Client(客户端):在main函数中创建表达式树,解释并计算表达式的值。

优缺点

优点

  1. 易于扩展:可以通过添加新的表达式类来扩展语言的语法,添加新操作无需修改现有的表达式类。
  2. 灵活性高:可以动态构建和解释表达式,适合解释和执行简单的DSL(领域特定语言)。

缺点

  1. 性能问题:对于复杂的语法规则或庞大的表达式,构建和解释的开销较大。
  2. 难以维护:表达式类的数量可能非常庞大,导致系统复杂度增加,难以维护。
  3. 有限应用场景:通常适用于简单的语言解释,复杂的语法解析需要更强大的解析器(如语法分析器)。

应用

  1. 解释简单的命令语言或配置语言:例如用于解释配置文件中的规则或处理脚本语言。
  2. 数学表达式解析:用于解析和计算数学表达式。
  3. 编译器或解释器的部分实现:在编译器中,用于解释特定语言的子集或生成代码的中间步骤。

访问器模式适合处理那些相对简单、易于表达的语法和表达式的解释操作,它在特定领域语言、数学表达式求值、规则引擎等场景中具有较高的实用性。

总结

  • 解析器模式的应用场合是解析器模式应用中的难点。只有满足业务规则频繁变化,且类似结构会不断重复出现。并且容易抽象为语法规则的问题,才适合使用解析器模式。

  • 使用解气模式来表示文法规则,从而可以使用。面向对象的技巧来方便的扩展文法。

  • 解析器模式比较适合简单的文法表示,对于复杂的文法表示解析模式会产生比较大的类层次结构。需要求助语法分析生成器这样的标准工具。

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

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

相关文章

无人机 PX4 飞控 | ROS应用层开发:指令(字符串)订阅功能

无人机 PX4 飞控 | ROS应用层开发&#xff1a;指令&#xff08;字符串&#xff09;订阅功能 指令&#xff08;字符串&#xff09;订阅功能代码测试 指令&#xff08;字符串&#xff09;订阅功能 为了通过键盘触发mavros 的不同功能&#xff0c;需要实现一个订阅字符串的功能 该…

【国外比较权威的免费的卫星数据网站】

国外比较权威的免费卫星数据网站有多个&#xff0c;它们各自在数据覆盖范围、分辨率、以及数据种类等方面具有不同的特点和优势。以下是一些推荐的网站&#xff1a; NASA Worldview 网址&#xff1a;https://worldview.earthdata.nasa.gov/简介&#xff1a;NASA Worldview显示…

p10 容器的基本命令

首先先拉取一个centos的镜像 命令&#xff1a;docker pull centos 新建容器并且启动 这里直接参考老师的命令吧 接下来是启动并且进入到容器当中去输入docker run -it centos /bin/bash这里是以交互的方式进入到容器中可以看到接下来的ls命令输出的东西就是一个Linux系统最…

Python和MATLAB和R对比敏感度函数导图

&#x1f3af;要点 深度学习网络两种选择的强制选择对比度检测贝叶斯自适应估计对比敏感度函数空间观察对比目标量化视觉皮质感知差异亮度、红/绿值、蓝/黄值色彩空间改变OpenCV图像对比度对比敏感度函数模型空间对比敏感度估计眼球运动医学研究空间时间颜色偏心率对比敏感度函…

mysql 不同版本安装不同端口

安装版本为Mysql8.0.11 先解压&#xff0c;解压后&#xff0c;包下创建my.ini文件内容如下&#xff1a; 注意&#xff1a;端口不能给别的mysql一样 [mysqld]# 设置3306端口port3307 # 自定义设置mysql的安装目录&#xff0c;即解压mysql压缩包的目录basedirD:\\rj\\mysql8.0.…

模型 SPIN销售法

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。探需挖痛&#xff0c;引导成交。 1 SPIN销售法的应用 1.1 提升工作效率的软件销售应用SPIN模型 一家制造企业正在寻求提升工作效率的解决方案。他们注意到员工在处理文件和任务时存在效率问题&#…

【Docker】Linux系统以及威联通QNAP部署思源笔记的通用教程

本文首发于 ❄️慕雪的寒舍 本文测试的是旧版本v2.11.4的部署方式&#xff0c;实测当前&#xff08;2024.08.15&#xff09;最新的v3.1.3版本也可以用相同的方式部署。本文的部署方式共写了三种&#xff0c;非qnap的linux系统也可以参考本文部署思源笔记。 阅读本文之前&#…

新审视零阶优化在内存高效大模型微调中的应用

人工智能咨询培训老师叶梓 转载标明出处 随着大模型模型规模的增大&#xff0c;反向传播&#xff08;BP&#xff09;所需的内存开销也日益增加&#xff0c;这对内存效率提出了挑战。尤其是在设备上训练等内存效率至关重要的应用场景中&#xff0c;解决这一问题变得尤为迫切。 …

【Linux】07.Linux 下的项目自动化构建工具——make/makefile

前言 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定&#xff0c;哪些文件需要先编译&#xff0c;哪些文件需要…

【Datawhale X 李宏毅苹果书 AI夏令营】Task1笔记

第三章&#xff1a;深度学习基础 3.1 局部极小值与鞍点 临界点&#xff0c;即梯度为零的点&#xff0c;包含局部极小值&#xff08;local minimum&#xff09;和鞍点&#xff08;saddle point&#xff09;。 梯度下降算法在接近鞍点的时候会变得非常慢&#xff0c;阻碍了继续…

机器学习:K-means算法(内有精彩动图)

目录 前言 一、K-means算法 1.K-means算法概念 2.具体步骤 3.精彩动图 4.算法效果评价 二、代码实现 1.完整代码 2.结果展示 3.步骤解析 1.数据预处理 2.建立并训练模型 3.打印图像 四、算法优缺点 1.优点 2.缺点 总结 前言 机器学习里除了分类算法&#xff0…

如何使用ssm实现计算机科学与技术学习网站的设计与开发

TOC ssm248计算机科学与技术学习网站的设计与开发jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&…

尝试给OpenHarmony4.0增加可以在动态库中使用的日志模块

尝试给OpenHarmony4.0增加可以在动态库中使用的日志模块 前言一、资源来源二、实践步骤1.修改OH内核并编译2.动态库增加welog打印3.设备验证打完收工 总结参考 前言 最近在搞OpenHarmony4.0蓝牙模块的适配&#xff0c;最主要的工作就是在libbt_vendor.z.so这个库的编写修改&am…

AWS 使用 Amazon EC2 控制台安装和配置 CloudWatch 代理以添加其他指标如内存

默认情况下&#xff0c;Amazon CloudWatch 提供基本指标&#xff08;例如 CPUUtilization 和 NetworkIn&#xff09;用于监控 Amazon EC2 实例。要收集其他指标&#xff0c;您可以在 EC2 实例上安装 CloudWatch 代理&#xff0c;然后将该代理配置为发出所选指标。您可以使用 Am…

网络安全售前入门04——审计类产品了解

目录 1.前言 2.数据库审计介绍 2.1产品架构功能 2.2应用场景 2.3部署形式 2.4产品价值 2.5选型依据 1.前言 为方便初接触网络安全售前工作的小伙伴了解网安行业情况,我制作一系统售前入门(安全产品,安全服务,法律法规等)文章介绍,希望能给初进网安职场的小伙伴提供…

【Qt】Qt系统 | Qt事件 | 定时器

文章目录 定时器QTimerEventQTimer获取系统日期及时间 定时器 Qt 中在进行窗口程序的处理过程中&#xff0c;经常要周期性的执行某些动作&#xff0c;或者制作一些动画效果&#xff0c;使用定时器可以实现这些需求。 定时器&#xff0c;会在间隔一定时间后&#xff0c;执行某一…

Git下载安装配置

Git的下载与安装 Git是一种分布式版本控制系统&#xff0c;用于跟踪文件和文件夹的变化。它最初由Linus Torvalds开发&#xff0c;用于管理Linux内核的源代码。Git的设计目标是&#xff1a;速度快、开发效率高、数据完整性和可靠性强。 Git通过创建一个存储库&#xff08;rep…

【FESCO福利专区-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

什么领域/方向的产品经理既有发展前景又能做的长久

前几天我在知乎上回答了一道“目前什么领域的产品经理比较有发展前景&#xff1f;有推荐的课程吗&#xff1f;”的问题&#xff0c;讲得还比较实在&#xff0c;于是在这里也顺便分享一下。 TOP1.商业产品经理 之所以这个方向能排在第1&#xff0c;我认为有3点理由。 第1点&a…

国产游戏技术能否引领全球?

国产游戏技术&#xff1a;引领全球还是任重道远&#xff1f; 近年来&#xff0c;伴随着中国科技和经济的迅猛发展&#xff0c;国产游戏行业也呈现出蓬勃发展的态势。从《原神》到《黎明杀机手机版》&#xff0c;多款国产游戏在国际市场上崭露头角。而国产游戏在画面渲染、物理…