PEP 269 – Python 的 Pgen 模块
- 作者:
- Jonathan Riehl <jriehl at spaceship.com>
- 状态:
- 推迟
- 类型:
- 标准跟踪
- 创建日期:
- 2001 年 8 月 24 日
- Python 版本:
- 2.2
- 发布历史:
摘要
正如 parser 模块公开了 Python 解析器一样,本 PEP 提议将用于创建 Python 解析器的解析器生成器 pgen 作为 Python 中的一个模块公开。
基本原理
在 Python 的发展历程中,关于创建 Python 编译器的讨论不胜枚举 [1]。这些讨论产生了几个 Python 解析器的实现,其中最著名的是 Python 标准库中当前提供的 parser 模块 [2] 和 Jeremy Hylton 的 compiler 模块 [3]。然而,尽管已经提出了多项语言更改建议 [4] [5],但对 Python 语法的实验却缺乏将 Python 绑定到用于构建 Python 的实际解析器生成器的优势。
通过提供一个类似于 Fred Drake Jr. 的解析器包装器,但针对 pgen 库的 Python 包装器,可以做出以下断言:
- 语法更改的参考实现将更容易开发。目前,语法更改的参考实现需要开发人员从命令行使用
pgen工具。然后,生成的解析器数据结构要么必须重新设计以与自定义 CPython 实现接口,要么包装为 C 扩展模块。 - 语法更改的参考实现将更容易分发。由于解析器生成器将在 Python 中可用,因此生成的解析器也应可从 Python 访问。因此,参考实现应以纯 Python 代码的形式提供,而不是使用现有 CPython 发行版的自定义版本,或作为可编译的扩展模块。
- 语法更改的参考实现将更容易与更广泛的受众讨论。这在某种程度上是第二个断言的结果,因为 Python 用户社区很可能比 CPython 开发人员社区更大。
- 由于额外的模块将是一个功能齐全的 LL(1) 解析器生成器,Python 中小型语言的开发将得到进一步增强。
规范
提议的模块将命名为 pgen。pgen 模块将包含以下函数:
parseGrammarFile (fileName) -> AST
parseGrammarFile() 函数将读取 fileName 指向的文件并创建一个 AST 对象。AST 节点将包含解析器生成器元语法的非终结符数字值。输出 AST 将是 parser 模块提供的 AST 扩展类的一个实例。输入文件中的语法错误将导致抛出 SyntaxError 异常。
parseGrammarString (text) -> AST
parseGrammarString() 函数将遵循 parseGrammarFile() 的语义,但接受语法文本作为字符串输入,而不是文件名。
buildParser (grammarAst) --> DFA
buildParser() 函数将接受一个 AST 对象作为输入并返回一个 DFA(确定性有限自动机)数据结构。DFA 数据结构将是一个 C 扩展类,就像 parser 模块中提供的 AST 结构一样。如果输入 AST 不符合为 pgen 元语法定义的非终结符代码,buildParser() 将抛出 ValueError 异常。
parseFile (fileName, dfa, start) -> AST
parseFile() 函数本质上是 PyParser_ParseFile() C API 函数的包装器。包装器代码将接受 DFA C 扩展类和文件名。将输出一个符合 token 模块中的词法值和 DFA 中包含的非终结符值的 AST 实例。
parseString (text, dfa, start) -> AST
parseString() 函数将以类似于 parseFile() 函数的方式操作,但接受解析文本作为参数。就像 parseFile() 将包装 PyParser_ParseFile() C API 函数一样,parseString() 将包装 PyParser_ParseString() 函数。
symbolToStringMap (dfa) -> dict
symbolToStringMap() 函数将接受一个 DFA 实例并返回一个字典对象,该字典将 DFA 的非终结符的数字值映射到在 DFA 的原始语法规范中找到的非终结符的字符串名称。
stringToSymbolMap (dfa) -> dict
stringToSymbolMap() 函数将输出一个字典,将输入 DFA 的非终结符名称映射到其对应的数字值。
如果映射生成函数和解析函数也是 DFA 扩展类的方法,将获得额外奖励。
实现计划
已经设计了一个巧妙的计划来完成这一增强:
- 重命名
pgen函数以符合 CPython 命名标准。此操作可能涉及向Include子目录添加一些头文件。 - 将 Makefile.pre.in 中的
pgenC 模块从唯一的pgen元素移动到 Python C 库。 - 对
parser模块进行任何必要的更改,以便 AST 扩展类了解可能存在它不理解的 AST 类型。对 AST 扩展类的初步检查表明它会跟踪树是套件还是表达式。
- 在
Modules目录中编写一个额外的 C 模块。C 扩展模块将实现 DFA 扩展类和上一节中概述的函数。 - 将新模块添加到构建过程。确实是黑魔法。
限制
根据本提案,未来的 Python 3000 设计者仍将受 Python 词法约定的约束。Python 词法分析器的添加、删除或修改超出了本 PEP 的范围。
参考实现
目前没有提供参考实现。曾经在 http://sourceforge.net/tracker/index.php?func=detail&aid=599331&group_id=5470&atid=305470 处提供了一个补丁,但该补丁已不再维护。
参考资料
版权
本文档已置于公共领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0269.rst