设计模式--解释器模式C++实现
2024-09-02 01:44:42
1定义
给定一门语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子
2类图
角色分析
AbstractExpression抽象解释器,具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和NonterminalExpression完成
TerminalExpression终结符表达式,实现与文法中的元素相关的解释操作,通常一个解释器模式中只能有一个终结符表达式,但有多个实例,敌营不同的终结符
NonterminalExpression非终结符,文法中的每条规则对应一个非终结表达式。
Context环境角色,
3实现
#pragma once
#include<stack>
#include<iostream>
using namespace std;
class Object;
class Context;
//抽象表达式 //抽象表达式是生成语法集合/语法树的关键,每个语法集合完成指定语法解析任务,通过递归调用方式完成
class Expression
{
public:
virtual Object* interpreter(Context *ctx) =
{
cout << "If you Can, you Don't" << endl;
return NULL;
};
};
//终结符表达式简单,主要处理场景元素和数据的转换
//终结符表达式
class TerminalExpression :public Expression
{
Object* interpreter(Context*ctx)
{
cout << "TerminalExpression::interpreter" << endl;
return NULL;
}
}; //每个非终结符表达式都表示一个文法规则,每个文法规则又只关心周边文法规则的结果,所以就会有递归调用而存在
//非终结符表达式
class NonterminalExpression :public Expression
{
public:
NonterminalExpression(Expression* x1, ...)
{
for (int i = ; i < ; ++i)
{
_st.push(x1);
}
}
Object *interpreter(Context*ctx)
{
//核心支出在于这里。。进行文法处理,并且产生递归调用
//if(typeid().name() != "TerminalExpression")
//递归调用
//文法处理
while (!_st.empty())
{
Expression* tp = _st.top();
_st.pop();
cout << "NoterminalExpression::interpreter" << endl;
tp->interpreter(ctx);
}
return NULL;
}
private:
stack <Expression*> _st;
};
class Context{
}; class Client
{
public:
void operator()()
{
Context *ctx = new Context();
stack<Expression*> st;
for (int i = ; i < ; ++i)
{
//进行语法判断,并且产生递归调用
st.push(new TerminalExpression());
st.push(new NonterminalExpression(new TerminalExpression()));
}
//for (int i = 0; i < 5; ++i)
//{
// //进行语法判断,并且产生递归调用
// st.push(new NonterminalExpression(new TerminalExpression()));
// st.push(new TerminalExpression());
//}
//产生一个完整的语法树,由各个具体的语法分析进行解析
Expression *exp = st.top();
exp->interpreter(ctx);
}
};
4应用
①优点:是一个简单的语法分析工具,扩展性良好,修改语法只需要修改相对应的非终结符表达式就可以了,扩展语法只需要增加非终结符类即可
②缺点
解释器模式引起类膨胀
采用递归调用方式
效率问题,循环和引用太多
③使用场景
重复发生的事情可以用解释器模式(日志分析等)
一个简单语法需要解释的场景
最新文章
- Git服务器搭建及配置
- RPi 2B apache2 mysql php5 and vsftp
- SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-006- 如何保持重定向的request数据(用model、占位符、RedirectAttributes、model.addFlashAttribute(";spitter";, spitter);)
- Remove Invalid Parentheses 解答
- iframe框架默认占满整个屏幕
- golang Date format
- [Swust OJ 179]--火柴棍(找规律)
- SQLAlchemy on the way
- shell 处理 文件名本身带星号的情况
- 如何定制 Calico 的 IP 池?- 每天5分钟玩转 Docker 容器技术(71)
- OWASP Top 10十大风险 – 10个最重大的Web应用风险与攻防
- [转帖]ODBC、OLEDB、ADO、ADO.NET
- alias命令使用
- 1226 快速幂 取余运算 洛谷luogu
- en-zh(科学技术)science and technology
- Ecust DIV3 k进制 【暴力不断优化】
- 逆袭之旅DAY15.东软实训.Oracle.约束、序列、视图、索引、用户管理、角色
- Linux mysql 5.7.23 主从复制(异步复制)
- POJ-3252 Avenger
- 小米盒子root及sshdroid安装
热门文章
- php 通过http user-agent判断是否为手机浏览器
- java synchronized关键字的底层实现
- python os模块一些常用操作
- Ubuntu14.04+caffe+cuda7.5 环境搭建以及MNIST数据集的训练与测试
- JCenter下载太慢?教你修改Maven仓库地址为国内镜像
- Django学习笔记之ORM字段和字段参数
- [pixhawk笔记]8-半物理仿真环境
- Java学习第一周博客
- 20145310 《Java程序设计》第8周学习总结
- JDK 中的监控与故障处理工具-05 (jstack)