PLY是纯粹由Python实现的Lex和yacc(流行的编译器构建工具)。PLY的设计目标是尽可能的沿袭传统lex和yacc工具的工作方式,包括支持LALR(1)分析法、提供丰富的输入验证、错误报告和诊断。因此,如果你曾经在其他编程语言下使用过yacc,你应该能够很容易的迁移到PLY上。
2001年,我在芝加哥大学教授“编译器简介”课程时开发了的早期的PLY。学生们使用Python和PLY构建了一个类似Pascal的语言的完整编译器,其中的语言特性包括:词法分析、语法分析、类型检查、类型推断、嵌套作用域,并针对SPARC处理器生成目标代码等。最终他们大约实现了30种不同的编译器!PLY在接口设计上影响使用的问题也被学生们所提出。从2001年以来,PLY继续从用户的反馈中不断改进。为了适应对未来的改进需求,PLY3.0在原来基础上进行了重大的重构。
由于PLY是作为教学工具来开发的,你会发现它对于标记和语法规则是相当严谨的,这一定程度上是为了帮助新手用户找出常见的编程错误。不过,高级用户也会发现这有助于处理真实编程语言的复杂语法。还需要注意的是,PLY没有提供太多花哨的东西(例如,自动构建抽象语法树和遍历树),我也不认为它是个分析框架。相反,你会发现它是一个用Python实现的,基本的,但能够完全胜任的lex/yacc。
本文的假设你多少熟悉分析理论、语法制导的翻译、基于其他编程语言使用过类似lex和yacc的编译器构建工具。如果你对这些东西不熟悉,你可能需要先去一些书籍中学习一些基础,比如:Aho, Sethi和Ullman的《Compilers: Principles, Techniques, and Tools》(《编译原理》),和O’Reilly’出版的John Levine的《lex and yacc》。事实上,《lex and yacc》和PLY使用的概念几乎相同。
- 0 一些翻译约定
- 1 前言和预备
- 2 介绍
- 3 PLY概要
- 4 Lex
- 4.1 Lex的例子
- 4.2 标记列表
- 4.3 标记的规则
- 4.4 标记的值
- 4.5 丢弃标记
- 4.6 行号和位置信息
- 4.7 忽略字符
- 4.8 字面字符
- 4.9 错误处理
- 4.10 构建和使用lexer
- 4.11 @TOKEN装饰器
- 4.12 优化模式
- 4.13 调试
- 4.14 其他方式定义词法规则
- 4.15 额外状态维护
- 4.16 Lexer克隆
- 4.17 Lexer的内部状态
- 4.18 基于条件的扫描和启动条件
- 4.19 其他问题
- 5 语法分析基础
- 6 Yacc
- 6.1 一个例子
- 6.2 将语法规则合并
- 6.3 字面字符
- 6.4 空产生式
- 6.5 改变起始符号
- 6.6 处理二义文法
- 6.7 parser.out调试文件
- 6.8 处理语法错误
- 6.9 行号和位置的跟踪
- 6.10 构造抽象语法树
- 6.11 嵌入式动作
- 6.12 Yacc的其他
- 7 多个语法和词法分析器
- 8 使用Python的优化模式
- 9 高级调试
- 9.1 调试lex()和yacc()命令
- 9.2 运行时调试
- 10 如何继续