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. 的解析器包装器的 Python 包装器,但将其目标对准 pgen
库,可以得出以下断言
- 语法更改的参考实现将更容易开发。目前,语法更改的参考实现需要开发人员使用命令行中的
pgen
工具。然后,生成的解析器数据结构要么必须重新处理以与自定义 CPython 实现交互,要么作为 C 扩展模块进行包装。 - 语法更改的参考实现将更容易分发。由于解析器生成器将在 Python 中可用,因此生成的解析器也应该可以从 Python 访问。因此,参考实现应该可以作为纯 Python 代码获得,而不是使用现有 CPython 发行版的自定义版本,或作为可编译的扩展模块。
- 语法更改的参考实现将更容易与更广泛的受众讨论。这在某种程度上源于第二个断言,因为 Python 用户社区很可能大于 CPython 开发人员社区。
- 在 Python 中开发小型语言将得到进一步增强,因为该附加模块将是一个功能齐全的 LL(1) 解析器生成器。
规范
建议的模块将称为 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 扩展类,就像 AST 结构在 parser
模块中提供的那样。如果输入 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 中将
pgen
C 模块从唯一的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
上次修改时间:2023-09-09 17:39:29 GMT