Python代码生成器

27 投票
2 回答
12760 浏览
提问于 2025-04-17 04:57

我想根据抽象语法树(AST)的描述来生成Python代码。

我之前对C语言做过静态分析,也在Python中写过AST访问器,所以对操作语法树还算有点底气,但我从来没有尝试过代码生成,现在想知道生成Python代码的最佳实践是什么。

具体来说,我希望能得到一些关于自动代码生成通常是怎么做的建议,或者有没有针对Python的库可以让这个任务变得简单一些。

我的最终目标是尝试做一些类似于csmith的东西,或者一个工具,让Python代码符合PEP8的规范。

2 个回答

5

自动生成代码通常有以下几种方式:

  • 打印包含代码片段的语句
  • 带有占位符的文本模板(可以想象成宏)

我认为更好的做法是:

  • 为目标代码片段构建一个抽象语法树(AST),然后进行格式化输出

但几乎没有人这样做,因为大多数工具都不支持。

Python的2to3工具提供了(我认为)目标AST和格式化输出的功能。

不过你没有问的一个问题是“从什么生成?”你必须以某种方式抽象地指定你想要生成的内容(否则就没有意义)。而且你的工具必须能够以某种方式读取这个规范。

许多代码生成方案是通过编写过程代码来调用上述生成机制;这些过程代码实际上充当了隐式规范。阅读这个规范“很简单”;它只是代码,使用的是代码生成器所用的语言。

一些代码生成方案使用某种图结构来提供一个框架,在这个框架上挂载规范的片段,以驱动代码生成。UML类图就是一个经典的例子。这些方案并不那么简单;你需要一个“规范读取器”(例如,UML图读取器,也叫XMI或类似的东西,或者如果你不使用UML,就需要某种规范解析器),然后你需要某种方法以有用的顺序遍历刚刚读取的规范(UML是图,有很多不同的方式可以访问),并调用代码生成步骤。

Python的2to3工具使用Python2解析器来读取“规范”。如果你想从Python2生成代码,那是可以的。我怀疑你并不想这样做。

一种最佳实践的方法是将读取/分析/遍历规范的能力与为目标语言生成AST的能力结合起来。

我们的DMS软件重构工具包是一个通用的程序分析和转换系统。它将“规范”(你可以定义的语法实例)解析为AST;它还允许你使用过程代码[如上所述]或使用模式匹配/替换(几乎是DMS独有的)来构建任意AST。DMS语言前端的一部分是一个格式化输出工具,可以从AST重新生成文本(这些通过代码的往返测试来验证:解析为AST,格式化AST,最终文本应该是一样的)。

如果你的语法不为DMS所知,它有非常好的解析器和格式化输出生成器,以及其他分析程序的支持机制。所有这些额外的工具通常在经典的解析器生成器或普通的“AST”包中是没有的。(我不知道2to3里有什么)。

这与Python的相关性在于,DMS有一个Python前端,以及许多其他语言的语法

所以,你可以使用DMS来解析你的规范,并使用AST生成Python代码,最后进行格式化输出。

19

你可以看看 2to3 这个工具,它是由Python的开发者们制作的,目的是为了自动把Python 2的代码转换成Python 3的代码。这个工具首先会把代码解析成一个树状结构,然后再从这个树中生成“修正过的”Python 3代码。

这个工具是一个很好的起点,因为它是Python官方的工具,得到了核心开发者的认可,也是推荐的从Python 2迁移到Python 3的路径之一。

另外,你也可以看看这个 codegen.py模块,它可以从Python的 ast 生成Python代码。

还有这个 SO问题,可能和你的问题有关(我没有标记它为重复问题,因为我不确定这两个问题的范围是否完全重叠)。

撰写回答