Heim  >  Artikel  >  Backend-Entwicklung  >  So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

WBOY
WBOYnach vorne
2023-05-10 12:46:061311Durchsuche

Einfache Visualisierung des Syntaxbaums mit vier arithmetischen Operationen

Wenn Sie es ausprobieren möchten, müssen Sie diese Python-Visualisierungsbibliothek installieren.

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

Parsen von AST

Pythons Ast-Bibliothek verfügt über eine Parse-Methode, die den eingehenden Inhalt in einen AST analysieren kann. Anschließend exportieren wir es mit ast.dump und drucken es aus.
Hinweis: indent Dieser Parameter ist erst nach Python 3.9 verfügbar. Wenn die Version früher ist, können Sie ihn entfernen, was sich nur auf das endgültige Ausgabeformat auswirkt. ast.dump 将其导出并打印。
注意:indent 这个参数是 Python 3.9 以后才有的,如果版本低的话,可以去掉,只会影响最后输出的格式。

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

好了,就是这么简单。我们已经做到了,因为这个库的功能很强大,但是这里只是用到一点点而已。其实这里已经可以看出基本的结构了,不过我的目的是生成这棵树的 JSON 表示。我想要使用上面的 Python 绘图库把它绘制出来,它所支持的输入是 JSON,并且它的格式为:

{
	"name": "A",
	"children": [
		"name": "B",
		"children": []
	]
}

粗糙的遍历方法

"""
Python's AST
利用 Python 的 ast 模块来解析表达式(简单的二元运算),
然后通过遍历语法树来生成 JSON 表示,再使用 PYthon 的库来
将其可视化。这个程序的目的是为了验证自己写的简易解析器是否正确。
"""

import ast
import json


# 操作类型和操作符映射的字典
OPERATORS = {
    ast.Add: "+",
    ast.Sub: "-",
    ast.Mult: "*",
    ast.Div: "/"
}


def generate(tree: ast.Module):
    """
    generate expression AST's representation of JSON
    """
    if not tree:
        raise Exception("Emtpy AST tree!")
    if tree.__class__ == ast.Module:
        print(json.dumps({
            "name": "Expr",
            "children": [DFS(tree.body[0].value)]  # type: ignore
        }, indent=4))


def DFS(node):
    """
    DFS AST
    """
    if not node:
        return {}

    if node.__class__ == ast.BinOp:
        return {
            "name": "BinOp",
            "children": [
                {
                    "name": "left",
                    "children": [
                        DFS(node.left)
                    ]
                },
                DFS(node.op),
                {
                    "name": "left",
                    "children": [
                        DFS(node.right)
                    ]
                }
            ]
        }

    if node.__class__ == ast.Constant:
        return {
            "name": "NUMBER",
            "children": [
                {
                    "name": str(node.value)  # Python 的绘图库,必须是字符串才能正常显示
                }
            ]
        }

    if node.__class__ in [ast.Add, ast.Sub, ast.Mult, ast.Div]:
        return {
            "name": "Op",
            "children": [
                {
                    "name": OPERATORS[node.__class__]
                }
            ]
        }

    # 这里我只处理 加减乘除和数字类型的运行
    raise Exception("There is not support extra type.")


if __name__ == "__main__":
    ast_tree = ast.parse("1+2+3+4+5")
    print(ast.dump(ast_tree, indent=4))
    generate(ast_tree)

运行结果:
我这里会输出两个东西,一个是 AST 的 dump;另一个是 AST 的 JSON 表示(逻辑结构的 JSON 表示,不是对象的 JSON 表示)。

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

渲染显示

把打印出来的 JSON 字符串复制进文件,命名为 data.json。我感觉直接输出到控制台蛮有意思的,我喜欢直接看到它的结果。
执行如下命令:pytm-cli -d TB -i data.json -o demo.html
在浏览器打开 demo.html 即可看到效果了。

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

主流的遍历方法

上面这种遍历方法虽然便于理解,但是难以扩展。AST 通常是通过 访问者模式 进行遍历的,而且 ast 库也提供了几种遍历方法。
因为这里只需要遍历来生成 JSON,并不需要修改AST本身,所以我们只看下面这两种即可。显然第一种是不能用的,原因已经用蓝色标记出来了。它自己说了如果你不关心上下文,因为生成 JSON 实际上是需要关注这个的。所以,我选择下面的 ast.NodeVisitor。使用它也很简单,继承这个类,然后对不同的节点写不同的处理逻辑就行了(这样把不同节点的逻辑分开了,降低了代码的耦合性)。

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python

完整代码

"""
Python's AST
利用 Python 的 ast 模块来解析表达式(简单的二元运算),
然后通过遍历语法树来生成 JSON 表示,再使用 PYthon 的库来
将其可视化。这个程序的目的是为了验证自己写的简易解析器是否正确。
"""

import ast
import json


# 操作类型和操作符映射的字典
OPERATORS = {
    ast.Add: "+",
    ast.Sub: "-",
    ast.Mult: "*",
    ast.Div: "/"
}

class JSONVisitor(ast.NodeVisitor):
    """
    JSON visitor: Traversal AST and generate JSON representation
    """

    def visit_Module(self, node):
        module = {
            "name": "Module",
            "children": []
        }
        for sub_node in node.body:
            module["children"].append(self.visit(sub_node))

        return module

    def visit_Expr(self, node):
        return {
            "name": "Expr",
            "children": [
                self.visit(node.value)
            ]
        }

    def visit_BinOp(self, node):
        return {
            "name": "BinOp",
            "children": [
                {
                    "name": "left",
                    "children": [
                        self.visit(node.left)
                    ]
                },
                self.visit(node.op),
                {
                    "name": "right",
                    "children": [
                        self.visit(node.right)
                    ]
                }
            ]
        }

    def visit_Constant(self, node):
        return {
            "name": "NUMBER",
            "children": [{
                "name": str(node.value)  # # Python 的绘图库,必须是字符串才能正常显示
            }]
        }

    def visit_Add(self, node):
        return self.__visit(node)

    def visit_Sub(self, node):
        return self.__visit(node)

    def visit_Mult(self, node):
        return self.__visit(node)

    def visit_Div(self, node):
        return self.__visit(node)

    def __visit(self, node):
        return {
            "name": "Op",
            "children": [{
                "name": OPERATORS[node.__class__]
            }]
        }


if __name__ == "__main__":
    ast_tree = ast.parse("1+2+3+4+5")
    visitor = JSONVisitor()
    json_str = visitor.visit(ast_tree)
    print(json.dumps(json_str, indent=4))

前面那个粗糙版本是直接从 Expr 开始的,这个优雅点的版本,我就把 Module

So visualisieren Sie den einfachen Syntaxbaum für vier arithmetische Operationen in Python

So realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in PythonGut Ja, so einfach ist das. Wir haben das getan, weil diese Bibliothek sehr leistungsfähig ist, hier aber nur wenig genutzt wird. Tatsächlich ist die Grundstruktur hier bereits zu sehen, aber mein Ziel ist es, eine JSON-Darstellung dieses Baums zu generieren. Ich möchte die obige Python-Zeichenbibliothek zum Zeichnen verwenden. Die unterstützte Eingabe ist JSON und ihr Format ist:

rrreee🎜Rough Traversal Method🎜rrreee🎜Run results:
Ich werde zwei Dinge ausgeben. Eines ist ein Dump von AST; das andere ist eine JSON-Darstellung von AST (eine JSON-Darstellung einer logischen Struktur, keine JSON-Darstellung eines Objekts). 🎜🎜So visualisieren Sie den Syntaxbaum für einfache vier arithmetische Operationen in Python🎜 🎜Rendering-Anzeige 🎜🎜Kopieren Sie die gedruckte JSON-Zeichenfolge in die Datei und nennen Sie sie data.json. Ich finde es sehr interessant, die Ergebnisse direkt auf der Konsole auszugeben.
Führen Sie den folgenden Befehl aus: pytm-cli -d TB -i data.json -o demo.html
Öffnen Sie demo.html im Browser , das heißt Sie können den Effekt sehen. 🎜🎜So visualisieren Sie den einfachen Syntaxbaum für vier arithmetische Operationen in Python🎜 🎜Mainstream Die Traversal-Methode🎜🎜Obwohl die obige Traversal-Methode leicht zu verstehen ist, ist es schwierig, sie zu erweitern. AST wird normalerweise über das Visitor-Muster durchlaufen, und die ast-Bibliothek bietet auch mehrere Traversierungsmethoden.
Da wir hier nur durchlaufen müssen, um JSON zu generieren, und den AST selbst nicht ändern müssen, betrachten wir nur die folgenden zwei Typen. Offensichtlich kann der erste nicht verwendet werden, und der Grund wurde blau markiert. Es spricht für sich, wenn Ihnen der Kontext egal ist, denn die Generierung von JSON ist eigentlich alles, worum Sie sich kümmern müssen. Also wähle ich unten ast.NodeVisitor aus. Die Verwendung ist auch sehr einfach. Erben Sie einfach diese Klasse und schreiben Sie dann unterschiedliche Verarbeitungslogik für verschiedene Knoten (dies trennt die Logik verschiedener Knoten und verringert die Kopplung des Codes). 🎜🎜So visualisieren Sie den einfachen Syntaxbaum für vier arithmetische Operationen in Python🎜 🎜Complete Die vorherige grobe Version des Codes 🎜rrreee🎜 begann direkt mit Expr. Für diese elegantere Version habe ich auch den Knoten Module hinzugefügt. 🎜🎜🎜🎜

Das obige ist der detaillierte Inhalt vonSo realisieren Sie die Visualisierung des Syntaxbaums einfacher vier arithmetischer Operationen in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen