最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python的簡單四則運(yùn)算語法樹可視化

 更新時(shí)間:2023年04月06日 09:53:47   作者:CrazyDragon_King  
這篇文章主要介紹了python的簡單四則運(yùn)算語法樹可視化,這篇文章的內(nèi)容也很簡單,就是給定一個(gè)四則運(yùn)算的表達(dá)式,畫出它的語法樹,需要的朋友可以參考下

簡單四則運(yùn)算語法樹可視化

前幾天有一篇博客是關(guān)于四則運(yùn)算和二叉樹的,我是把四則運(yùn)算用二叉樹寫出來(我是用的 JSON 的形式來存儲(chǔ)和表達(dá)的),并計(jì)算最終的結(jié)果。最近,也在繼續(xù)這個(gè)方面的東西,不過遇到一些問題。所以想著先做一些簡單是事情,也許會(huì)更好吧。這篇博客的內(nèi)容也很簡單,就是給定一個(gè)四則運(yùn)算的表達(dá)式,畫出它的語法樹。如果了解過這方面知識(shí)的人,應(yīng)該都能大致畫出來,不過其實(shí)也是挺費(fèi)事的。如果包含了多層括號(hào)嵌套,也注定了是一個(gè)費(fèi)時(shí)費(fèi)力的事情。這種機(jī)械的事情,讓程序自己來做是最好不過的了。所以,接下來我會(huì)用到 Python 自帶的 ast 庫來解析四則運(yùn)算(殺雞用牛刀,哈哈)。

如果想要?jiǎng)邮謬L試一下,需要安裝一下這個(gè) python 可視化庫。

在這里插入圖片描述

解析 AST

Python 的 ast 庫有一個(gè) parse 方法,可以把傳入的內(nèi)容,解析成一個(gè) AST。然后我們使用 ast.dump 將其導(dǎo)出并打印。
注意:indent 這個(gè)參數(shù)是 Python 3.9 以后才有的,如果版本低的話,可以去掉,只會(huì)影響最后輸出的格式。

在這里插入圖片描述

好了,就是這么簡單。我們已經(jīng)做到了,因?yàn)檫@個(gè)庫的功能很強(qiáng)大,但是這里只是用到一點(diǎn)點(diǎn)而已。其實(shí)這里已經(jīng)可以看出基本的結(jié)構(gòu)了,不過我的目的是生成這棵樹的 JSON 表示。我想要使用上面的 Python 繪圖庫把它繪制出來,它所支持的輸入是 JSON,并且它的格式為:

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

粗糙的遍歷方法

"""
Python's AST
利用 Python 的 ast 模塊來解析表達(dá)式(簡單的二元運(yùn)算),
然后通過遍歷語法樹來生成 JSON 表示,再使用 PYthon 的庫來
將其可視化。這個(gè)程序的目的是為了驗(yàn)證自己寫的簡易解析器是否正確。
"""

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__]
                }
            ]
        }

    # 這里我只處理 加減乘除和數(shù)字類型的運(yùn)行
    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)

運(yùn)行結(jié)果:
我這里會(huì)輸出兩個(gè)東西,一個(gè)是 AST 的 dump;另一個(gè)是 AST 的 JSON 表示(邏輯結(jié)構(gòu)的 JSON 表示,不是對(duì)象的 JSON 表示)。

在這里插入圖片描述

渲染顯示

把打印出來的 JSON 字符串復(fù)制進(jìn)文件,命名為 data.json。我感覺直接輸出到控制臺(tái)蠻有意思的,我喜歡直接看到它的結(jié)果。
執(zhí)行如下命令:pytm-cli -d TB -i data.json -o demo.html
在瀏覽器打開 demo.html 即可看到效果了。

在這里插入圖片描述

主流的遍歷方法

上面這種遍歷方法雖然便于理解,但是難以擴(kuò)展。AST 通常是通過 訪問者模式 進(jìn)行遍歷的,而且 ast 庫也提供了幾種遍歷方法。
因?yàn)檫@里只需要遍歷來生成 JSON,并不需要修改AST本身,所以我們只看下面這兩種即可。顯然第一種是不能用的,原因已經(jīng)用藍(lán)色標(biāo)記出來了。它自己說了如果你不關(guān)心上下文,因?yàn)樯?JSON 實(shí)際上是需要關(guān)注這個(gè)的。所以,我選擇下面的 ast.NodeVisitor。使用它也很簡單,繼承這個(gè)類,然后對(duì)不同的節(jié)點(diǎn)寫不同的處理邏輯就行了(這樣把不同節(jié)點(diǎn)的邏輯分開了,降低了代碼的耦合性)。

在這里插入圖片描述

完整代碼

"""
Python's AST
利用 Python 的 ast 模塊來解析表達(dá)式(簡單的二元運(yùn)算),
然后通過遍歷語法樹來生成 JSON 表示,再使用 PYthon 的庫來
將其可視化。這個(gè)程序的目的是為了驗(yàn)證自己寫的簡易解析器是否正確。
"""

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))

前面那個(gè)粗糙版本是直接從 Expr 開始的,這個(gè)優(yōu)雅點(diǎn)的版本,我就把 Module 節(jié)點(diǎn)也添加進(jìn)去了。

在這里插入圖片描述

說明

這個(gè)東西挺有趣的,如果想要了解這些知識(shí)的話,可以來看看這個(gè)圖示。這也相當(dāng)于給自己寫了一個(gè)小工具了,我之后還會(huì)用到它來對(duì)比我自己生成的 AST,如果不一樣,那一定是我寫的有問題了。

到此這篇關(guān)于python的簡單四則運(yùn)算語法樹可視化的文章就介紹到這了,更多相關(guān)python四則語法樹可視化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python+SeaTable實(shí)現(xiàn)計(jì)算兩個(gè)日期間的工作日天數(shù)

    Python+SeaTable實(shí)現(xiàn)計(jì)算兩個(gè)日期間的工作日天數(shù)

    在實(shí)際的項(xiàng)目管理、任務(wù)管理、工作計(jì)劃等場(chǎng)景中,某些時(shí)間段會(huì)涉及雙休日、法定節(jié)假日,甚至還有公司自定義的工作時(shí)間安排,所以就需要計(jì)算出兩個(gè)日期間的實(shí)際工作日天數(shù)。本文用Python+SeaTable實(shí)現(xiàn)這一需求,需要的可以參考一下
    2022-07-07
  • Matplotlib 繪制餅圖解決文字重疊的方法

    Matplotlib 繪制餅圖解決文字重疊的方法

    這篇文章主要介紹了Matplotlib 繪制餅圖解決文字重疊的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 基于Python實(shí)現(xiàn)屏幕取色工具

    基于Python實(shí)現(xiàn)屏幕取色工具

    屏幕取色小工具?是一種實(shí)用的軟件工具,主要用于從屏幕上精確獲取顏色值,非常適合設(shè)計(jì)、編程等需要精確配色的領(lǐng)域,下面我們看看如何利用Python編寫一個(gè)屏幕取色工具吧
    2024-12-12
  • Python二叉樹初識(shí)(新手也秒懂!)

    Python二叉樹初識(shí)(新手也秒懂!)

    二叉樹是一種簡單的樹形結(jié)構(gòu),其每個(gè)節(jié)點(diǎn)的分支節(jié)點(diǎn)數(shù)有0,1或2個(gè),下面這篇文章主要給大家介紹了關(guān)于Python二叉樹的相關(guān)資料,本文介紹的非常通俗易懂,新手也秒懂,需要的朋友可以參考下
    2022-05-05
  • Python使用xpath對(duì)解析內(nèi)容進(jìn)行數(shù)據(jù)提取

    Python使用xpath對(duì)解析內(nèi)容進(jìn)行數(shù)據(jù)提取

    XPath 使用路徑表達(dá)式來選取HTML/ XML 文檔中的節(jié)點(diǎn)或節(jié)點(diǎn)集,節(jié)點(diǎn)是通過沿著路徑 (path) 或者步 (steps) 來選取的,本文將給大家介紹Python使用xpath對(duì)解析內(nèi)容進(jìn)行數(shù)據(jù)提取的方法,需要的朋友可以參考下
    2024-05-05
  • Python3.7+tkinter實(shí)現(xiàn)查詢界面功能

    Python3.7+tkinter實(shí)現(xiàn)查詢界面功能

    這篇文章主要介紹了Python3.7+tkinter實(shí)現(xiàn)查詢界面功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 使用Python3中的gettext模塊翻譯Python源碼以支持多語言

    使用Python3中的gettext模塊翻譯Python源碼以支持多語言

    這篇文章主要介紹了使用Python3中的gettext模塊翻譯Python源碼以支持多語言,其中翻譯Python源碼只是作為示例以展示gettext的功能和用法,需要的朋友可以參考下
    2015-03-03
  • Pandas-Cookbook 時(shí)間戳處理方式

    Pandas-Cookbook 時(shí)間戳處理方式

    今天小編就為大家分享一篇Pandas-Cookbook 時(shí)間戳處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Pandas如何將Timestamp轉(zhuǎn)為datetime類型

    Pandas如何將Timestamp轉(zhuǎn)為datetime類型

    這篇文章主要介紹了Pandas如何將Timestamp轉(zhuǎn)為datetime類型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • python3.3實(shí)現(xiàn)乘法表示例

    python3.3實(shí)現(xiàn)乘法表示例

    這篇文章主要介紹了python3.3實(shí)現(xiàn)乘法表示例,需要的朋友可以參考下
    2014-02-02

最新評(píng)論

南木林县| 夏邑县| 太和县| 宁武县| 镇安县| 彩票| 新余市| 资中县| 楚雄市| 军事| 游戏| 固安县| 平果县| 称多县| 鄂伦春自治旗| 武安市| 布尔津县| 方正县| 武乡县| 红桥区| 云龙县| 麟游县| 都江堰市| 丹巴县| 乐业县| 孟津县| 都昌县| 柯坪县| 赤水市| 霍邱县| 苗栗市| 咸宁市| 乡宁县| 凤庆县| 石城县| 莎车县| 青田县| 井研县| 辽宁省| 礼泉县| 响水县|