c#设计模式-行为型模式 之 解释器模式

🚀简介

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

解释器模式包含以下主要角色

  1. 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主 要包含解释方法 interpret()。
  2. 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结 符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  3. 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法 中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  4. 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有 解释器共享的数据,后面的解释器可以从这里获取这些值。
  5. 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语 法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

🚀案例

下面是一个简单的解释器模式的C#实现,这个例子中,我们将创建一个IExpression接口和实现了IExpression接口的具体类AddExpressionSubtractExpressionContext是一个解释器上下文类,它将用于存储和管理解释器的状态。

🐤抽象角色AbstractExpression

public interface AbstractExpression
{public  int interpret(Context context);public string toString();
}

🐤终结符表达式角色

public class Value : AbstractExpression
{private int _value;public Value(int value){_value = value;}public int interpret(Context context){return _value;}public string toString(){return _value.ToString();}
}

🐤非终结符表达式角色 加减法表达式

/// <summary>
/// 加法
/// </summary>
public class Plus : AbstractExpression
{private AbstractExpression _left;private AbstractExpression _right;public Plus(AbstractExpression left, AbstractExpression right){_left = left;_right = right;}public int interpret(Context context){return _left.interpret(context) + _right.interpret(context);}public String toString(){return "(" + _left.toString() + " + " + _right.toString() + ")";}
}/// <summary>
/// 减法
/// </summary>
public class Minus : AbstractExpression
{private AbstractExpression _left;private AbstractExpression _right;public Minus(AbstractExpression left, AbstractExpression right){_left = left;_right = right;}public int interpret(Context context){return _left.interpret(context) - _right.interpret(context);}public string toString(){return "(" + _left.toString() + " - " + _right.toString() + ")";}
}

🐤终结符表达式角色 变量表达式

public class Variable:AbstractExpression{private string _name;public Variable(string name){_name = name;}public int interpret(Context context){return context.GetValue(this);}public string toString(){return _name;}
}

🐤环境(Context)角色

public class Context
{private Dictionary<Variable, int> map = new Dictionary<Variable, int>();public void Assign(Variable var, int value){map[var] = value;}public int GetValue(Variable var){int value = map[var];return value;}
}

🐳测试类

class MyClass
{public static void Main(string[] args){Context context = new Context();Variable a = new Variable("a");Variable b = new Variable("b");Variable c = new Variable("c");Variable d = new Variable("d");Variable e = new Variable("e");context.Assign(a, 1);context.Assign(b, 2);context.Assign(c, 3);context.Assign(d, 4);context.Assign(e, 5);AbstractExpression expression = new Minus(new Plus(new Plus(newPlus(a, b), c), d), e);Console.WriteLine(expression + "= " +expression.interpret(context));}
}

👻运行结果!

🚀优缺点

优点:

  1. 易于改变和扩展文法。 由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。 每一条文法规则都可以表示为一个类,因此可以方便地实现一个简单的语言。
  2. 实现文法较为容易。 在抽象语法树中每一个表达式节点类的实现方式都是相似的,这些类的代码编写都不会特别复杂。
  3. 增加新的解释表达式较为方便。 如果用户需要增加新的解释表达式只需要对应增加一个新的终结符表达式或非终结符表达式类,原 有表达式类代码无须修改,符合 "开闭原则"。

缺点:

  1. 对于复杂文法难以维护。 在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护。
  2. 执行效率较低。 由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢,而 且代码的调试过程也比较麻烦。

使用场景:

  1. 当语言的文法较为简单,且执行效率不是关键问题时。
  2. 当问题重复出现,且可以用一种简单的语言来进行表达时。
  3. 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候。

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

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

相关文章

Unity之ShaderGraph如何实现边缘光效果

前言 游戏中最常用的一个效果就是边缘光了&#xff0c;既可以做物体的高亮效果&#xff0c;也可以给人物皮肤表面添加光泽。如下图所示&#xff1a; 实现原理 边缘光的原理就是Fresnel节点的底层逻辑。 Fresnel&#xff1a;菲涅尔效应是根据视角不同表面上反射率不同的效应…

同为科技TOWE智能PDU引领数据中心机房远控用电安全高效

随着数据中心的环境变得更加动态和复杂&#xff0c;许多数据中心都在对数据中心管理人员施加压力&#xff0c;要求提高可用性&#xff0c;同时降低成本&#xff0c;提升效率。新一代高密度服务器和网络设备的投入使用&#xff0c;增加了对更高密度机架的需求&#xff0c;并对整…

添加Mybatis框架支持

配置环境 1.老项目 在pom.xml中使用generate ->edit starts->添加下面俩 2.新项目 然后运行发现会有报错 2.1这是因为没有配置数据库连接信息 spring:datasource:url: jdbc:mysql://localhost:3306/java2023?characterEncodingutf8&useSSLfalse # MySQL数…

攻防演练蓝队|Windows应急响应入侵排查

文章目录 日志分析web日志windows系统日志 文件排查进程排查新增、隐藏账号排查启动项/服务/计划任务排查工具 日志分析 web日志 dirpro扫描目录&#xff0c;sqlmap扫描dvwa Python dirpro -u http://192.168.52.129 -b sqlmap -u "http://192.168.52.129/dvwa/vulnera…

Express入门指南(详细)

文章目录 &#x1f7e2; Express⭐️ 1.初始Express✨安装✨使用Express 搭建一台服务器 ⭐️2.Express-基本路由✨1.使用字符串模式的路由路径示例&#xff1a;✨2.使用正则表达式的路由路径示例&#xff1a;✨3.中间件浅试(demo) ⭐️3.Express-中间件✨1.应用级中间件✨2.路…

特斯拉pre-test (Go)

特斯拉pre-test &#xff08;Go&#xff09; 1 Q12 Q23 Q3 1 Q1 原文&#xff1a; You are given an implementation of a function Solution that, given a positive integer N, prints to standard output another integer, which was formed by reversing a decimal repres…

PCLVisualizer显示点云的深层用法

以下代码均是在QT中使用QVTKOpenGLNativeWidget的简单教程以及案例-CSDN博客文章的基础上&#xff0c;修改按钮对应的槽函数中的程序。 1.显示文件中点云颜色属性信息&#xff0c;利用PointCloudColorHandlerRGBField得到每个点云对应的颜色。 pcl::PointCloud<pcl::PointX…

【Spring Cloud】网关Gateway的请求过滤工厂RequestRateLimiterGatewayFilterFactory

概念 关于微服务网关Gateway中有几十种过滤工厂&#xff0c;这一篇博文记录的是关于请求限流过滤工厂&#xff0c;也就是标题中的RequestRateLimiterGatewayFilterFactory。这个路由过滤工厂是用来判断当前请求是否应该被处理&#xff0c;如果不会被处理就会返回HTTP状态码为42…

Ruby和面向对象技术

Ruby和许多极为流行的编程语言都是面向对象的。多数的面向对象编程语言&#xff0c;每个对象都是一个样例或者既定类的实例以及独立对象的行为。 一、创建一个通用对象 创建一个通用对象 obj Object.new定义通用对象的行为 def obj.talk puts "I am an object"p…

分享一份适合练手的软件测试实战项目

最近&#xff0c;不少读者托我找一个能实际练手的测试项目。开始&#xff0c;我觉得这是很简单的一件事&#xff0c;但当我付诸行动时&#xff0c;却发现&#xff0c;要找到一个对新手友好的练手项目&#xff0c;着实困难。 我翻了不下一百个web网页&#xff0c;包括之前推荐练…

Pytorch从零开始实战05

Pytorch从零开始实战——运动鞋识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——运动鞋识别环境准备数据集模型选择数据可视化模型预测总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.0.1cu118…

点击切换播放图片

<template><!-- banner组件 --><div class"wrap-box"><div class"image-container"><img :src"currentImage" alt"Image"></div><div class"controls"><div class"btn&q…