`
RednaxelaFX
  • 浏览: 3048095 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

[链接] 可以在Python里用的parsing library

阅读更多
有室友的毕业设计是做程序切片相关的,需要对代码做解析;指导老师建议他们用Python为实现语言,所以看来是需要找点适合Python使用的parsing library。解析源码这种事情正好是我熟悉的领域,就自告奋勇说看看能不能帮上啥忙。不过听说要解析的源语言或许是C++我就冒冷汗……||||||

手写parser真是太痛苦了,虽然我已经做了很多次但我还是不想建议室友也重复我的痛苦。特别是像C++那么复杂的语言 =v=
总之调查一下有些什么可选项,先记在这边再说。

有点想推荐用ANTLR来生成lexer和parser,因为ANTLRWorks用于编写词法和语法规则相当方便。Jython的解析器就是用ANTLR来生成的,ANTLR官网首页上甚至有Python之父Guido van Rossum的赞词:
Guido van Rossum 写道
I'm actually really liking ANTLR! I have a pretty darn good velocity with...

我手写RD系解析器的时候一般也会用ANTLRWorks来写个语法来确认一下构思中的语法有没有错,然后再手工转换成具体实现。不过问题是ANTLR的库普遍都比较“大”,里面东西也挺多挺复杂的,或许上手要花点时间?
说到大,刚看了一下ANTLR的Python target,看来没我原本想像的那么大。antlr_python_runtime-3.1.2-py2.5.egg才145KB。还行。
要是室友用ANTLR,那我能跟他分享的经验就会多一些,例如说ANTLRWorks的使用之类。在ANTLR官网的Grammars一栏里有些现成的C/C++语法文件,包括Sun在NetBeans中使用C/C++预处理器和解析器的语法文件。可惜Sun的那两个文件是对应ANTLR v2.7的,而且有很重的NetBeans自身的痕迹,不能直接拿来用。
要开始用ANTLR与Python的组合很简单:
1、先到ANTLR官网的下载页面下载一个ANTLRWorks+ANTLR的包,用于进行语法编辑和调试;
2、到ANTLR的Python target页面下载对应Python 2.5的运行时库
3、阅读ANTLR 3 Python Target的文档来了解使用Python target的注意点;
4、阅读Example: Book Examples Modified for Python来了解一个简单的lexer/parser的写法,找到感觉;
5、自己继续探索吧…… =w=

ANTLR之外,PLY看来也是个不错的选择。它可以看做是lex/yacc的纯Python实现,最大的优势就是它完全继承了lex/yacc系工具的特征,把符合lex/yacc的规则写在doc string里就行,这样就能最大限度的利用到处都能找到的lex/yacc相关的教学资料,包括我手上的几本书,以及许多现成的C/C++的lex/yacc例子;作者当初是为了教授编译器课程而编写这个库的,有较强的教学背景,适合学生使用;另外,作为纯Python实现的解析器库,它的速度在可接受范围内(作者提供的例子称它比ANTLR快)。
在Google Code上有个pycparser项目使用PLY来实现了C的解析和代码生成;SourceForge上也有个CppHeaderParser.py用PLY来解析C++头文件以获取类的结构信息。应该说还是有些实际应用的。
PLY-3.1的整个tarball才143KB,相当小。里面包括了一些例子,例如一个完整的Dartmouth BASIC解释器的Python实现。有lex/yacc基础的话这个库上手应该很快。不过用它来解析C++或许会比较吃力……

室友说最近的任务就是周末前用Python写一个C++的词法分析器,貌似是要输出关键字出现的行号还是怎样,具体要求还没问清楚。这个的话用ANTLR、PLY或者手写倒都不困难就是了。C++词法分析里最麻烦的或许是字符串的分析吧?里面的各种转义序列都得考虑到,规则写起来冗长。其它都还好,前提是代码已经经过了预处理……自己做预处理的话又是件超麻烦的事情。在当前C++规范下嵌套的泛型声明的尖括号间还是得有空白字符,所以这个现在还不是问题。

Ned Batchelder做了份颇有用的Python parsing tools列表,如果要找其它可选项的话可以从这个列表里发掘一下。
突然想起的事情:貌似不少库都对空白字符有自己的主张,喜欢自动忽略它们;很多时候这带来了方便,但如果要解析Python或者F#这些用缩进表示块结构的语言就麻烦了。到底是该让用户显式指定忽略规则,还是默认带有忽略空白字符的规则好呢?

有人推荐pyparsing,不过我稍微看了些例子,第一感觉是我不太喜欢它处理语法规则的方式:它主要通过运算符重载和一些工厂函数来实现fluent API式的internal DSL来表达语法规则,但我觉得这样的代码在Python里看起来挺怪的。
从官网上引用段例子过来:
pyparsing 写道
from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!" # <-- grammar defined here
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )
#=> Hello, World! -> ['Hello', ',', 'World', '!']

Python用来做internal DSL总觉得有点硬(语法层面上)然而又不够硬(类型层面上)。说语法硬主要是Python库能对语法做的定制余地不大,而且Python社区也比较喜欢统一的做事方式;说类型不够硬是指静态类型语言能够通过精巧的类层次/API设计来在编译时对fluent API做“语法检查”,而Python的变量没有类型所以fluent API要是写错了也得到运行时才能发现。嘛,静态/动态方面的观点总是有争议的,我这里纯粹是自己的感觉,没有想说服别人的意思。Boo用于internal DSL就比Python来得方便,多得语法宏。
呵呵,事实上我自己在写的一个库也是用fluent API来表达语法规则的;跟pyparsing一样,我也是重载了+来表示顺序结构、|来表示选择结构,等;但那样的代码出现在C#里我就没觉得很奇怪。呃诶……

可视化工具里除了ANTLRWorks之外我也很喜欢新的Oslo的Intellipad,不过Oslo的运行时依赖于.NET Framework,算了,不用来推荐给室友。据说Oslo team的人用MGrammar写过VB和C#的语法?呵呵,it's got all the potentials, let's just wait and see what comes out of it.
还有些别的语法编辑器不过貌似要收费……呜,收费的暂时无视。

今天先记这么多。要是有时间的话手写个简单的词法分析器作为例子也可以……不过现在我想睡觉了
P.S. Python自己的编译器是如何实现的呢?可以关注一下PEP-339的描述。是一个典型的LL(1)解析器解析出AST之后,生成CFG然后生成bytecode。
分享到:
评论

相关推荐

    pyparsing(文档+安装包+例子)【Python里用的parsing library】

    在Python编程中,`pyparsing`是一个非常实用的库,专门用于处理文本解析任务。它提供了一种声明式的方法来定义语法规则,使得开发人员能够轻松地创建复杂的语法解析器,而无需深入了解编译原理或正则表达式的复杂性...

    Python 3.7 is a programming language

    Python's standard library supports many Internet protocols: HTML and XML JSON E-mail processing. Support for FTP, IMAP, and other Internet protocols. Easy-to-use socket interface. And the Package ...

    python3.6.5参考手册 chm

    Python参考手册,官方正式版参考手册,chm版。以下摘取部分内容:Navigation index modules | next | Python » 3.6.5 Documentation » Python Documentation contents What’s New in Python What’s New In ...

    Python Programming Blueprints 2018

    How to build useful, real-world applications in the Python programming language Key Features Deliver scalable and high-performing applications in Python. Delve into the great ecosystem of Python ...

    Python Cookbook, 2nd Edition

    Fuzzy Parsing of Dates Recipe 3.8. Checking Whether Daylight Saving Time Is Currently in Effect Recipe 3.9. Converting Time Zones Recipe 3.10. Running a Command Repeatedly Recipe 3.11. ...

    libxml2-python-2.7.7.win32-py2.6

    libxml2 is a software library for parsing XML documents. It is also the basis for the libxslt library which processes XSLT-1.0 stylesheets.

    python出现"IndentationError: unexpected indent"错误解决办法

    - 如果你的编辑器允许,可以在设置中禁用将Tab键转换为空格的功能,以避免无意中混用两种缩进方式。 4. **手动检查**: - 仔细检查报错行附近的代码,确保所有同级的代码行缩进一致。 - 特别注意那些容易忽略的...

    pyparsing:用于创建PEG解析器的Python库

    3. **python3 parsing-expression-grammar**:这表示pyparsing支持Python3,并且可以处理解析表达式语法。 4. **python-3** 和 **python2**:标签分别指出pyparsing兼容Python 3和Python 2版本。 5. **text-...

    ctparse:在python中解析自然语言时间表达式

    4. **易于集成**:作为一个 Python 库,`ctparse` 可以方便地与其他 Python 项目集成,提供灵活的 API 接口,让开发者能够在自己的应用中快速实现时间解析功能。 5. **自定义扩展**:`ctparse` 可能允许用户根据...

    Foundations for Analytics with Python O-Reilly-2016-Clinton W. Brownley

    It transitions to an illustration of potential problems with this method of parsing and then presents an example of how to avoid these potential problems by parsing a CSV file with Python’s csv ...

    gpxpy:gpx-py是python GPX解析器。 GPX(GPS eXchange格式)是GPS轨道的基于XML的文件格式

    您可以在看到它的运行情况。 还有一个gpxpy的Golang端口: 。 如果您的轨道缺少高程数据,另请参见 用法 import gpxpy import gpxpy . gpx # Parsing an existing file: # ------------------------- gpx_file = ...

    GreynirPackage:用于冰岛语的Greynir NLP解析器,为PyPI打包

    GreynirPackage作为一个Python库,可以方便地通过`pip`等工具安装,然后在用户的Python项目中导入和使用。 **Python3** 是Python语言的最新版本,相比早期的Python2,它引入了许多改进和新特性,包括更好的错误处理...

Global site tag (gtag.js) - Google Analytics