当前位置: 首页 > news >正文

[Python设计模式] 第27章 正则表达式——解释器模式

github地址:https://github.com/cheesezh/python_design_patterns

解释器模式

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

解释其模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的橘子。这样就可以构建一个解释器,该解释器通过解释这些橘子来解决该问题。

比如说,我们常常会在字符串中搜索匹配的字符或者判断一个字符串是否符合我们的规定格式,此时我们一般会用正则表达式技术。因为匹配字符串的需求在很多地方都会用到,而且行为类似,与其为每一个特定需求都写一个算法函数,不如使用一种通用的搜索算法来解释执行一个正则表达式,该正则表达式定义了待匹配字符串的集合。

正则表达式就是解释器模式的一种用用,解释器为正则表达式定义了一个文法,如何表示一个特定的正则表达式,以及如何解释这个正则表达式。

解释器模式主要包含以下几个类:

from abc import ABCMeta, abstractmethod


class AbstractExpression():
    """
    抽象表达式类,声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享
    """
    __metaclass__ = ABCMeta
    
    @abstractmethod
    def interpret(self, context):
        pass
    

class TerminalExpression(AbstractExpression):
    """
    终结符表达式,实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个interpret()方法。
    文法中的每一个终结符都有一个具体终结符表达式与之相对应。
    """
    def interpret(self, context):
        print("终结符表达式")
        
        
class NontermialExpression(AbstractExpression):
    """
    非终结符表达式,为文法中的非终结符实现解释操作。对文法中每一条规则R1,R2,...Rn都需要一个具体的非终结符表达式类。
    通过实现抽闲表达式的interpret()方法实现解释操作。解释操作以递归的方式调用上 main所提到的代表R1,R2,...Rn中各
    个符号的实例变量。
    """
    def interpret(self, context):
        print("非终结符表达式")
        
        
class Context():
    """
    上下文类,包含解释器之外的一些全局信息
    """
    def __init__(self):
        self.input = None
        self.output = None
        
        
def main():
    """
    客户端代码,构建表示该文法定义的语言中一个特定的句子的抽象语法树。
    """
    context = Context()
    exp_list = []
    exp_list.append(TerminalExpression())
    exp_list.append(NontermialExpression())
    exp_list.append(TerminalExpression())
    exp_list.append(NontermialExpression())
    
    for exp in exp_list:
        exp.interpret(context)
        
main()
终结符表达式
非终结符表达式
终结符表达式
非终结符表达式

点评

当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式[DP]。

用了解释器模式,就意味着可以很容易的改变和扩展文法,因为该模式使用类来表示文法规则,你可以使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接便携。

解释器模式也有不足,解释器模式为文法中每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时,使用其他技术,如语法分析程序或者编译器生成器来处理[DP]。

相关文章:

  • springboot 使用 @Scheduled 注解实现任务调度 以及相关踩坑记录
  • centos虚拟机安装,配置静态ip可以访问网络
  • java倒序按行读文本文件ReversedLinesFileReader
  • 打造RecyclerView的n级列表
  • python之异常处理模块
  • 微服务通信策略
  • 《Python从小白到大牛》第9章 数据结构
  • 写给33岁的自己:为之奋斗一生的事业
  • ElasticSearch6.3.2------入门
  • 技术团队
  • 阿里云表格存储使用教程
  • ROS设备的性价比图
  • jQuery跳转到页面指定位置
  • PMP每日一题
  • TimesTen数据库的备份和恢复
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 345-反转字符串中的元音字母
  • angular2 简述
  • axios 和 cookie 的那些事
  • CentOS 7 修改主机名
  • css的样式优先级
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • HTTP中的ETag在移动客户端的应用
  • Java程序员幽默爆笑锦集
  • Java多线程(4):使用线程池执行定时任务
  • mockjs让前端开发独立于后端
  • MySQL几个简单SQL的优化
  • Otto开发初探——微服务依赖管理新利器
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • Redis在Web项目中的应用与实践
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • select2 取值 遍历 设置默认值
  • socket.io+express实现聊天室的思考(三)
  • storm drpc实例
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • WebSocket使用
  • 关于List、List?、ListObject的区别
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 前端_面试
  • 软件开发学习的5大技巧,你知道吗?
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 线上 python http server profile 实践
  • 学习Vue.js的五个小例子
  • 智能合约开发环境搭建及Hello World合约
  • ​iOS安全加固方法及实现
  • ​Linux·i2c驱动架构​
  • ​VRRP 虚拟路由冗余协议(华为)
  • #if #elif #endif
  • #Z0458. 树的中心2
  • #大学#套接字
  • #微信小程序(布局、渲染层基础知识)
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (¥1011)-(一千零一拾一元整)输出
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (论文阅读40-45)图像描述1