Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Python神器】使用lex进行规则解释

【Python神器】使用lex进行规则解释

作者头像
明月AI
发布于 2021-10-28 06:49:22
发布于 2021-10-28 06:49:22
1.4K02
代码可运行
举报
文章被收录于专栏:野生AI架构师野生AI架构师
运行总次数:2
代码可运行

背景


在一个复杂的文章搜索匹配的需求里,匹配规则已经实现,但是原有的规则写法过于复杂,需要进行简化,例如原规则:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
("小鹏" >= 1) and ("P7" >= 1)

这个规则的意思实际上是:小鹏这个关键词的出现次数大于等于1,P7这个关键词出现次数也大于等于1。

但是这个语法显然很罗嗦,客户要求进行简化。客户希望可以简化成这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
小鹏 and P7

这是客户的习惯,实际上参考搜索引擎的查询语法是可以更加简洁的“+小鹏 +P7”,不过这暂时不再考虑范围。

上面这个只是一个简化的示例,实际客户写的匹配规则是可能很复杂的。

使用lex进行解释


同事们好像觉得这个功能实现很难,没什么信心,其实只要理解其中的逻辑,并不复杂,就算不借助工具也能实现,单单用正则和循环也能解决。不过,使用神器lex显然是更好的解决方案(lex经常和yacc搭配使用,不过我们的需求比较简单,并不需要用到yacc)。

下面是一个简单的示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import ply.lex as lex

# List of token names.
tokens = (
    'KEYWORD',  # 关键词
    'LPAREN',   # 左括号
    'RPAREN',   # 右括号
    'LOGIT',    # 逻辑操作
    'CMP',      # 比较操作
)

# 分组
t_LPAREN  = r'\('
t_RPAREN  = r'\)'
# 忽略空格及tab
t_ignore  = ' \t'

# 关键词
def t_KEYWORD(t):
    # 双引号内的,或者不非空格组成的字符串(不含括号)
    r'("[^\"]+")|([^\s\(\)]+)'
    val_lower = t.value.lower()
    if val_lower in {'and', 'or', 'not'}:
        t.type = 'LOGIT'
        return t
    if val_lower in {'>=', '>', '==', '<=', '<'}:
        t.type = 'CMP'
        return t
    if t.value[0] == '"':
        t.value = t.value[1:-1]    # 关键词统一去掉双引号
    return t

 # Error handling rule
def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)
# Build the lexer
lexer = lex.lex()

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def parse_tokens(data):
    print('')
    lexer.input(data)
    while True:
        tok = lexer.token()
        if not tok: 
            break
        print(tok)

data = '小鹏 and P7'
parse_tokens(data)

# 带双引号的测试
data = '小鹏  and "P7 价格"'
parse_tokens(data)

# 带括号及比较操作的测试
data = '(小鹏 >= 2) and "P7 价格"'
parse_tokens(data)

测试对应的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LexToken(KEYWORD,'小鹏',1,0)
LexToken(LOGIT,'and',1,3)
LexToken(KEYWORD,'P7',1,7)

LexToken(KEYWORD,'小鹏',1,0)
LexToken(LOGIT,'and',1,4)
LexToken(KEYWORD,'P7 价格',1,8)

LexToken(LPAREN,'(',1,0)
LexToken(KEYWORD,'小鹏',1,1)
LexToken(CMP,'>=',1,4)
LexToken(KEYWORD,'2',1,7)
LexToken(RPAREN,')',1,8)
LexToken(LOGIT,'and',1,10)
LexToken(KEYWORD,'P7 价格',1,14)

有了这个结果,要处理成完整的表达式已经是很简单了。

lex与yacc


有了这两个神器,想实现一门简单的语言也是不难的。而且,理解了这两个工具,非常有助于理解编程语言本身,可谓大有益处。

程序员还是要保持好奇心。

备注:

ply是Python Lex Yacc的缩写,官方文档:http://www.dabeaz.com/ply/ply.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 野生AI架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Python】Ply 简介
Ply 是一个纯 python 的词法分析和语法分析库,包括两个模块:lex 和 yacc
JuneBao
2022/10/26
2.9K0
TiDB SQL Parser 的实现
其中,SQL Parser的功能是把SQL语句按照SQL语法规则进行解析,将文本转换成抽象语法树(AST),这部分功能需要些背景知识才能比较容易理解,我尝试做下相关知识的介绍,希望能对读懂这部分代码有点帮助。
mazhen
2023/11/24
7760
TiDB SQL Parser 的实现
编译入门 - 从零实现中文计算器
“如果你不知道编译器咋工作的你就不知道电脑是咋工作的。” -- STEVE YEGGE
羽月
2022/10/08
8740
编译入门 - 从零实现中文计算器
antlr4入门篇
ANTLR实际上有两件事:一种将您的语法转换为Java(或其他目标语言)的解析器/词法分析器的工具,以及生成的解析器/词法分析器所需的运行时。即使您使用ANTLR Intellij插件或ANTLRWorks来运行ANTLR工具,生成的代码仍将需要运行时库。
山行AI
2020/08/18
4.8K0
antlr4入门篇
Golang 编译原理 计算器(通俗易懂)
本文不需要你掌握任何编译原理的知识。 只需要看懂简单的golang语言即可, 完整的代码示例在GIT
李海彬
2019/03/07
1.1K0
Golang 编译原理 计算器(通俗易懂)
TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现
PingCAP 发布了 TiDB 的源码阅读系列文章,让我们可以比较系统的去学习了解TiDB的内部实现。最近的一篇《SQL 的一生》,从整体上讲解了一条 SQL 语句的处理流程,从网络上接收数据,MySQL 协议解析和转换,SQL 语法解析,查询计划的制定和优化,查询计划执行,到最后返回结果。
PingCAP
2018/03/22
4.7K3
TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现
自己动手写编译器:从正则表达式到NFA状态机
在编译器开发中有两个非常重要的工具名为lex和yacc,他们是编译器的生成器。本质上我们不需要一行行去完成编译器的代码,只需要借助这两个工具,同时制定好词法解析和语法解析的规则后,这两个工具就会自动帮我们把代码生成,我们后续的任务就是使用go语言将这两个工具实现。
望月从良
2022/12/02
1.4K0
自己动手写编译器:从正则表达式到NFA状态机
Stanford公开课《编译原理》学习笔记(2)递归下降法
课程里涉及到的内容讲的还是很清楚的,但个别地方有点脱节,建议课下自己配合经典著作《Compilers-priciples, Techniques and Tools》(也就是大名鼎鼎的龙书)作为补充阅读。
大史不说话
2019/10/08
1.2K0
Stanford公开课《编译原理》学习笔记(2)递归下降法
Antlr4实战:统一SQL路由多引擎
ANTLR是一款功能强大的语法分析器生成器,可用来读取、处理、执行和转换结构化文本或二进制文件。它被广泛应用于学术界和工业界构建各种语言、工具和框架。Antlr在Hadoop整个生态系统应用较为广泛,如Hive 词法文件是Antlr3写的;Presto词法文件也Antlr4实现的;SparkSQL词法文件是用Presto的词法文件改写的;还有HBase的访问客户端Phoenix也用Antlr工具进行SQL解析的等等。
用户7600169
2022/04/25
10.5K1
Antlr4实战:统一SQL路由多引擎
Go程序生命周期
本文希望能讲清楚一个Go程序从开始写下第一行代码到程序完全退出这期间都发生了什么事情,当然每个程序的执行逻辑千差万别,但这里想讲清楚的事情是所有程序都共通的事情,所有程序都需要经历的处理逻辑。
wish42
2021/10/19
8800
(1)PHP内核 - 玩转php的编译与执行
曾几何时php一不小心闯入了我生活,php语法竟然和C语言那么莫名的相似,这是最初php给我的感受,当接触的php时间越来越多的时候,php也没有那般生涩难懂,但是偶尔一些的新的php 设计思想,也会思考许久,不知是从什么时候开始了php另一个世界。我想应该是从那次的类型转换开始的,"1e12"字符串类型在转化为数字类型变量时,不同的php版本下转换结果截然不同,有的就变成了数字1,有的却可以正常的识别为科学计数法10^12,在这个地方就已经悄悄的埋下了一枚种子。
猿哥
2019/07/10
2K0
Java词法树与自定义关键字 发布于
Java词法树(语法树)这种树形结构是Java源码的一种抽象表示,它以图形化的方式反映出代码的语法结构,从而帮助开发者更好地理解和解析程序的语义。
DioxideCN
2023/10/21
2960
Java词法树与自定义关键字
                        
                            发布于
如何用Python编写一个Lisp解释器
这篇文章有两个目的:一是展示如何实现一个计算机语言的解释器,二是演示如何使用 Python 3 构造 Lisp 的一种方言 Schema,作者把自己的这个语言解释器称作 Lispy。几年前,作者曾展示过如何用 Java 和 Common Lisp 写 Schema 解释器。而本次的目的很纯粹,作者会尽可能简明扼要为大家进行介绍。
AI科技大本营
2019/08/15
1.5K0
如何用Python编写一个Lisp解释器
python爬取微博关键词搜索帖子,并封装成界面软件,适合文科生
在信息爆炸的时代,社交媒体成为了大众表达观点、分享生活的重要阵地,而微博凭借其强大的实时性和广泛的影响力,一直占据着社交媒体的头部位置。每当热点事件发生,微博热搜总是率先登场,成为众人瞩目的焦点。
python迷3016
2025/03/27
2270
python爬取微博关键词搜索帖子,并封装成界面软件,适合文科生
Go 反射机制详解及实例 【Go语言圣经笔记】
Go语言提供了一种机制,能够在运行时更新变量或检查它们的值、调用它们的方法和它们支持的内在操作,而不需要在编译时就知道这些变量的具体类型。这种机制被称为反射(这里反射的定义和其他语言大体相同)。反射也可以让我们将类型本身作为第一类的值类型处理。
Steve Wang
2021/12/06
1.3K0
CLUE社区最新神器!PromptCLUE:大规模多任务Prompt预训练中文开源模型
PromptCLUE支持几十个不同中文类型的任务,具有较好的零样本学习能力和少样本学习能力。
新智元
2023/01/07
1.4K0
CLUE社区最新神器!PromptCLUE:大规模多任务Prompt预训练中文开源模型
贷前系统ElasticSearch实践总结
索引好比是一本书前面的目录,能加快数据库的查询速度。了解索引的构造及使用,对理解ES的工作模式有非常大的帮助。
宜信技术学院
2019/06/28
1.2K0
一份开源的编码规范:代码整洁的 JavaScript
作者根据 Robert C. Martin 《代码整洁之道》总结了适用于 JavaScript 的软件工程原则《Clean Code JavaScript》。
落落落洛克
2021/03/08
9480
《收获,不止SQL优化》读书笔记
假如使用了Hint语法: /*+ gather_plan_statistics */,就可以省略步骤1,直接执行步骤2和3,获取执行计划
SmileNicky
2019/07/09
1.5K0
一句python,一句R︱python中的字符串操作、中文乱码、NaN情况(split、zip...)
先学了R,最近刚刚上手python,所以想着将python和R结合起来互相对比来更好理解python。最好就是一句python,对应写一句R。
悟乙己
2019/05/26
3.3K0
推荐阅读
相关推荐
【Python】Ply 简介
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验