[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]。
[Python设计模式] 第27章 正则表达式——解释器模式的更多相关文章
- python设计模式第十七天【解释器模式】
1.应用场景 (1)解释预先定义的文法 2.代码实现 #!/usr/bin/env python #!_*_ coding:UTF-8 _*_ from abc import ABCMeta, abs ...
- C#设计模式学习笔记:(23)解释器模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8242238.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第十一个模式-- ...
- 我所理解的设计模式(C++实现)——解释器模式(Interpreter Pattern)
概述: 未来机器智能化已然成为趋势,现在手机都能听懂英语和普通话,那我大中华几万种方言的被智能化也许也是趋势,我们的方言虽然和普通话相似,但是还是不一样的.这可能需要一个新的语法分析器来帮助我们. 我 ...
- 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)
1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...
- 第27章 结构型模式大PK
27.1 代理模式 VS 装饰模式 27.1.1 代理模式 (1)场景:客人找运动员代理要求安排运动员参加比赛 (2)说明:代理人有控制权,可以拒绝客人的要求,也可以答应安排,甚至自己下去跑(因为有些 ...
- Head First 设计模式 第3章 装饰者模式
第3章 装饰者模式 1.定义/说明 动态.透明的将职责附加到对象上(或从对象上撤销),而不影响其他对象.若要扩展功能,装饰者模式提供了比继承更富有弹性的替代方案. 2.介绍 首先让我们先来介绍一下场景 ...
- 【设计模式】行为型11解释器模式(Interpreter Pattern)
解释器模式(Interpreter Pattern) 解释器模式应用场景比较小,也没有固定的DEMO,中心思想就是自定义解释器用来解释固定的对象. 定义:给定一个语言,定义它的文法表示,并定义一个 ...
- [Python设计模式] 第1章 计算器——简单工厂模式
github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...
- [Python设计模式] 第24章 加薪审批——职责链模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用程序模拟以下情景 员工向经理发起加薪申请,经理无权决定,需要向总监汇报, ...
随机推荐
- HDU5692 Snacks DFS序 线段树
去博客园看该题解 题目 HDU5692 Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的 ...
- .net core webapi 将localhost改成ip地址
用管理员身份运行vs 添加引用 using Microsoft.AspNetCore.Cors; 修改 public void Configure(IApplicationBuilder app, I ...
- STC15W408AS简单使用教程-简单的光强检测!
第一步:搭建开发环境 安装最新版本的STC_ISP程序烧录软件,链接:http://pan.baidu.com/s/1slLPnOD 密码:6bov 安装keil C51的51系列单片机集成IDE软件 ...
- JavaEE 之 RESTful
1.RESTful a.定义:一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等 ...
- Linux学习之RPM包管理-yum管理(十七)
Linux学习之RPM包管理-yum管理 目录 IP地址配置 网络yum源 yum命令 光盘yum源搭建 IP地址配置 IP+子网掩码就可以在局域网(内网)使用. IP+子网掩码+网关+DNS就可以访 ...
- Linux下的计划任务at,batch,crontab
0x00前言: 继上次的windows计划任务后,拓展研究下linux下的计划任务,能够执行计划任务有3个命令at,batch,crontab 所谓的计划任务就是定时启动某个程序,可以是一组shell ...
- npm、webpack、vue-cli 快速上手版
Node.js npm 什么是Node.js 以及npm 简单的来说 Node.js 就是运行在服务端的JavaScript,基于Chrome V8 引擎的. npm 是Node.js 的包管理 ...
- string method and regular expresions
<!doctype html> <!DOCTYPE html> <html> <head> <meta charset="utf-8&q ...
- git基于某个分支创建分支
1.git checkout -b 新分支名 老分支名 git checkout -b dev_20150909 master git ls -tree 分支名字
- js点击回到顶部
---恢复内容开始--- <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...