python - 如何将 python 代码转换为解析树并返回原始代码?

标签 python parsing tree parse-tree

我希望能够将 python 代码(字符串)转换为解析树,在树级别对其进行修改,然后将树转换为代码(字符串)。当转换为解析树并返回代码时没有任何树级修改,生成的代码应该与原始输入代码完全匹配。

我想为此使用 python。我找到了 astparser python 模块,但是 ast 树丢失了有关原始代码的信息。至于parser 模块,我似乎无法弄清楚如何操作解析树或将其转换为代码。

这是我目前所拥有的。

import ast
import astor # pip install astor
import parser

code = 'hi = 0'
ast_tree = ast.parse(code)
code_from_ast = astor.to_source(tree) # 'hi = 0\n'
parser_tree = parser.suite(code)
code_from_parser = ???

最佳答案

正如您所提到的,内置的 ast 模块不会保留很多格式信息(空格、注释等)。 在这种情况下,您需要具体语法树(例如 LibCST)而不是抽象语法树。 (可以通过pip install libcs​​t安装)

这是一个示例,展示了如何将代码从 hi = 0 更改为 hi = 2 通过将代码解析为树、改变树并将树渲染回源代码代码。 可以在 https://libcst.readthedocs.io/ 中找到更高级的用法

In [1]: import libcst as cst

In [2]: code = 'hi = 0'

In [3]: tree = cst.parse_module(code)

In [4]: print(tree)
Module(
    body=[
        SimpleStatementLine(
            body=[
                Assign(
                    targets=[
                        AssignTarget(
                            target=Name(
                                value='hi',
                                lpar=[],
                                rpar=[],
                            ),
                            whitespace_before_equal=SimpleWhitespace(
                                value=' ',
                            ),
                            whitespace_after_equal=SimpleWhitespace(
                                value=' ',
                            ),
                        ),
                    ],
                    value=Integer(
                        value='0',
                        lpar=[],
                        rpar=[],
                    ),
                    semicolon=MaybeSentinel.DEFAULT,
                ),
            ],
            leading_lines=[],
            trailing_whitespace=TrailingWhitespace(
                whitespace=SimpleWhitespace(
                    value='',
                ),
                comment=None,
                newline=Newline(
                    value=None,
                ),
            ),
        ),
    ],
    header=[],
    footer=[],
    encoding='utf-8',
    default_indent='    ',
    default_newline='\n',
    has_trailing_newline=False,
)

In [5]: class ModifyValueVisitor(cst.CSTTransformer):
   ...:     def leave_Assign(self, node, updated_node):
   ...:         return updated_node.with_changes(value=cst.Integer(value='2'))
   ...:

In [6]: modified_tree = tree.visit(ModifyValueVisitor())

In [7]: modified_tree.code
Out[7]: 'hi = 2'

关于python - 如何将 python 代码转换为解析树并返回原始代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56487216/

相关文章:

python - Python 新手 : Getting TypeError: unhashable type: 'list'

python - 从朴素的本地日光时间转换为 Pandas 的朴素本地标准时间

parsing - 无法用 LL 表示的 LR 语法示例?

parsing - 基于层数的递归解析

oop - 访问者设计模式和深度优先搜索之间的区别?

java - 预排序决策二叉树打印输出

python - 如何在 Google Colab 中编辑和保存文本文件 (.py)?

python - 有条件地拆分 PySpark 列表中的逗号分隔值

python - 如何序列化 beautifulsoup 访问路径?

serialization - Clojure:存储和编译大型派生数据结构