解析器模式(C++)

news2025/1/11 0:13:24

定义

给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。

应用场景

  • 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
  • 在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

结构

在这里插入图片描述

代码示例

//Interpreter.h
/****************************************************/
#ifndef INTERPRETER_H
#define INTERPRETER_H
#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;
};


#endif
//test.cpp
/****************************************************/
#include "Interpreter.h"

#include <unordered_map>
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;
}

运行结果
在这里插入图片描述

要点总结

  • Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式。
  • 使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
  • Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interperter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

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

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

相关文章

JavaWeb三大组件——Filter

目录 过滤器作用 注册Filter 父pom文件 pom文件 注解方式 TokenFilter LogFilter Logout 启动类 使用FilterRegistrationBean注册 结果 过滤器作用 过滤器用途主要包括&#xff1a;对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过…

UE4/5 GAS技能系统入门2 - AttributeSet

在GAS系统中对属性进行修改需要用到GE&#xff08;Gameplay Effect&#xff09;&#xff0c;而这又涉及到AttributeSet这样的概念。 AttributeSet用于描述角色的属性集合&#xff0c;如攻击力、血量、防御力等&#xff0c;与GAS系统整合度较高&#xff0c;本文就来讲一讲Attri…

【1++的数据结构】之二叉搜索树

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的数据结构】 文章目录 一&#xff0c;什么是二叉搜索树二&#xff0c;二叉搜索树的操作及其实现2.1 插入操作及其实现2.2 查找操作及其实现2.3 删除操作及其实现 三&#xff0c;构造及其析构四…

docker版jxTMS使用指南:使用jxTMS采集数据之一

本文讲解了如何jxTMS的数据采集与处理框架并介绍了如何用来采集数据&#xff0c;整个系列的文章请查看&#xff1a;docker版jxTMS使用指南&#xff1a;4.4版升级内容 docker版本的使用&#xff0c;请查看&#xff1a;docker版jxTMS使用指南 4.0版jxTMS的说明&#xff0c;请查…

【搭建PyTorch神经网络进行气温预测】

import numpy as np import pandas as pd import matplotlib.pyplot as plt import torch import torch.optim as optim import warnings warnings.filterwarnings("ignore") %matplotlib inlinefeatures pd.read_csv(temps.csv)#看看数据长什么样子 features.head…

图像 分割 - Fast-SCNN: Fast Semantic Segmentation Network (arXiv 2019)

Fast-SCNN: Fast Semantic Segmentation Network - 快速语义分割网络&#xff08;arXiv 2019&#xff09; 摘要1. 引言2. 相关工作2.1 语义分割的基础2.2 DCNN的效率2.3 辅助任务预训练 3. 提议的Fast-SCNN3.1 动机3.2 网络架构3.2.1 学习下采样3.2.2 全局特征提取器3.2.3 特征…

侯捷 C++面向对象编程笔记——10 继承与虚函数

10 继承与虚函数 10.1 Inheritance 继承 语法&#xff1a;:public base_class_name public 只是一种继承的方式&#xff0c;还有protect&#xff0c;private 子类会拥有自己的以及父类的数据 10.1.1 继承下的构造和析构 与复合下的构造和析构相似 构造是由内而外 Container …

试图将更改推送到 GitHub,但是远程仓库已经包含了您本地没有的工作(可能是其他人提交的修改)

这通常是由于其他人或其他仓库推送到了相同的分支上&#xff0c;导致您的本地仓库和远程仓库之间存在冲突。 错误信息&#xff1a; To github.com:8upersaiyan/CKmuduo.git ! [rejected] main -> main (fetch first) error: failed to push some refs to github.com:8upers…

Webots与MATLAB联合仿真环境配置

1. 版本 系统&#xff1a;Win10 matlab版本&#xff1a;2023a webots版本&#xff1a;R2020b 2.安装 MATLAB MinGW-w64 C/C Compiler 在使用matlab写控制器之前&#xff0c;需要给matlab安装 MATLAB MinGW-w64 C/C Compiler&#xff0c;因为需要matlab与c进行交互。 下载地址…

K8S系列文章之 Kind 部署K8S的 服务发布

安装kind 下载 https://github.com/kubernetes-sigs/kind/releases/download/0.17.0/kind-linux-amd64 执行以下命令&#xff1a; mv kind-linux-amd64 /usr/local/bin/kind chmod 777 /usr/local/bin/kind 之前需要先在本地主机安装好docker yum -y install yum-utils d…

门面模式(C++)

定义 为子系统中的一组接口提供一个一致(稳定) 的界面&#xff0c;Facade模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用(复用)。 应用场景 上述A方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合&#xff0c;随着外部客户程序和各子…

无锚框原理 TOOD:Task-aligned One-stage Object Detection

无锚框原理 TOOD&#xff1a;Task-aligned One-stage Object Detection 一 摘要二 引言TOOD设计 三 具体设计Task-aligned Head任务对齐的预测器 TAP预测对齐 TAL 任务对齐学习Task-aligned Sample Assignment多任务损失 一 摘要 一阶段目标检测通常通过优化两个子任务来实现&…

计算机毕业设计题目大全(论文+源码)_kaic

图书信息管理系统的设计与实现(论文源码)_kaic 基于Spring Boot的学院宿舍管理系统的设计与实现(论文源码)_kaic 在线考试系统设计与实现(论文源码)_kaic 基于javaee的就业管理系统设计与实现(论文源码)_kaic 基于VUE和SpringBoot的微信小程序商城的设计与实现(论文源码)_kaic …

iOS - 开发者账号续订会员资格更换订阅的账号

文章目录 前言开发环境续订会员资格转让账户持有人验证身份1. 实名认证2. 联系信息 更换订阅的账号最后 前言 公司有一个开发者账号快到期了需要续订会员资格&#xff0c;刚注册时是用我自己的个人账号完成的订阅购买。现在想来有点不妥&#xff0c;于是尝试更换用于订阅的账号…

STM32 CubeMX USB_MSC(存储设备U盘)

STM32 CubeMX STM32 CubeMX USB_MSC(存储设备U盘&#xff09; STM32 CubeMX前言 《使用内部Flash》——U盘一、STM32 CubeMX 设置USB时钟设置USB使能UBS功能选择FATFS功能 二、代码部分修改代码"usbd_storage_if.c"修改代码"user_diskio.c"main函数初始化插…

CVE-2022-23134(Zabbix setup 访问控制登录绕过)

目录 一、题目 二、进入题目 一、题目 靶标介绍&#xff1a; Zabbix Sia Zabbix是拉脱维亚Zabbix SIA&#xff08;Zabbix Sia&#xff09;公司的一套开源的监控系统。该系统支持网络监控、服务器监控、云监控和应用监控等。 Zabbix 存在安全漏洞&#xff0c;该漏洞源于在初始…

【VSCode】报错:出现段错误解决办法 (Segmentation fault)

VScode报错&#xff1a;Segmentation fault (core dumped)的解决办法 解决Program received signal SIGSEGV, Segmentation fault.的辛酸 Linux环境下段错误的产生原因及调试方法小结 Linux下的段错误Segmentationfault产生的原因及调试方法经典.pdf 解决办法&#xff1a;

C高级第四讲

1、思维导图 2、写一个shell函数&#xff0c;获取用户的uid和gid并使用变量接收 #!/bin/bash function get_id() {uidid -u ubuntugidid -g ubuntu } get_id echo "uid:$uid" echo "gid:$gid"运行结果 3、排序 冒泡排序 /* ------------------------…

【MongoDB】初识、安装MongoDB

目录 一、MongoDB主要应用场景 二、MongoDB简介 三、MongoDB相关特点 四、MongoDB的安装 一、MongoDB主要应用场景 传统的数据库如MySQL在应对三高场景时显得力不从心 三高&#xff1a; High performance 对数据库高并发读写的需求 High Storage 对海量数据的高效率存储和 …

hacksudo3 通关详解

环境配置 一开始桥接错网卡了 搞了半天 改回来就行了 信息收集 漏洞发现 扫个目录 大概看了一眼没什么有用的信息 然后对着login.php跑了一下弱口令 sqlmap 都没跑出来 那么利用点应该不在这 考虑到之前有过dirsearch字典太小扫不到东西的经历 换个gobuster扫一下 先看看g…