成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

何為語法樹

hikui / 633人閱讀

摘要:原文鏈接何為語法樹什么是語法樹你是否曾想過,這個世界存在這么多語言的意義。語法樹,計(jì)算機(jī)描述世界真理的樹狀結(jié)構(gòu)。不同的語言,都會配之不同的語法分析器,而語法分析器是把源代碼作為字符串讀入解析,并建立語法樹的程序。

原文鏈接:BlueSun | 何為語法樹

什么是語法樹?

你是否曾想過,這個世界存在這么多語言的意義。

假如現(xiàn)在你面前有一個物體,它是一個不規(guī)則的圓體,整個身體通紅,頭部還有一根細(xì)長稍微彎曲偏右呈棕色的圓柱體。
在中文我們稱之為「蘋果」,
在英文我們稱之為「Apple」,
在日文中我們稱之為「アップル」,
在法語中我們稱之為「pomme」,
在德語中我們稱之為「Apfel」,
無論用不同的語言,針對這個物體在文字上、發(fā)音上都完全不一樣,但這個物體確確實(shí)實(shí)的存在這個時空上,顏色、氣味、形狀都不曾因?yàn)檎Z言而改變過。

無論這個世界存在多少語言,它們所描述的真理都不曾改變過。

或者說,真理就存在那里,可以用不同的語言的不同表達(dá)方式描述出來。那么計(jì)算機(jī)的世界,這么多編程的語言,C、C++、Java、C#、JavaScript、Python、Go、Ruby等等等,它們共同所描述的真理是什么?

我們知道人類語言上,無論什么語種,都會有「主語」「動詞」「賓語」「標(biāo)點(diǎn)符號」來描述一個現(xiàn)實(shí)世界所發(fā)生的事件。
而在計(jì)算機(jī)編程語言上,無論什么語種,都會有「類型」「運(yùn)算符」「流程語句」「函數(shù)」「對象」等概念來表達(dá)計(jì)算機(jī)中存在內(nèi)存中的0和1,以及背后運(yùn)算與邏輯。

語法樹,計(jì)算機(jī)描述世界真理的樹狀結(jié)構(gòu)。

不同的語言,都會配之不同的語法分析器,而語法分析器是把源代碼作為字符串讀入、解析,并建立語法樹的程序。語法的設(shè)計(jì)和語法分析器的實(shí)現(xiàn)是決定語言外在表現(xiàn)的重要因素。
什么是語法樹?摘自Wiki一段:

在計(jì)算機(jī)科學(xué)中,抽象語法樹(abstract syntax tree 或者縮寫為 AST),或者語法樹(syntax tree),是源代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式,這里特指編程語言的源代碼。樹上的每個節(jié)點(diǎn)都表示源代碼中的一種結(jié)構(gòu)。之所以說語法是「抽象」的,是因?yàn)檫@里的語法并不會表示出真實(shí)語法中出現(xiàn)的每個細(xì)節(jié)。

一則簡單的例子

如果我們需要讓計(jì)算機(jī)幫忙算一下 「1加2再乘以3」 的結(jié)果,該怎么表達(dá)呢?
現(xiàn)在我們大多數(shù)的現(xiàn)代編程語言,都是使用「中綴表達(dá)式」的方式來編寫運(yùn)算,比如JavaScript:

(1 + 2) * 3

而FORTH語言則使用「后綴表達(dá)式」,這基本上與日語中的語序是一致的:

1 2 + 3 *

LISP語言使用的「前綴表達(dá)式」:

( * (+ 1 2) 3)

我們再看一下這三種表達(dá)式的語法樹:

可以看出,對于這三種簡單的語言,它們只是在這個語法樹上按不同的規(guī)則遍歷而已。三者的代碼看起來差別很大,但實(shí)際上所用的樹結(jié)構(gòu)是相同的。

先來看看Python的語法樹

通過Python語言自帶的庫文件ast,我們可以查看特定的代碼被轉(zhuǎn)換成怎樣的語法樹。

>>> import ast
>>> ast.dump(ast.parse("(1 + 2) * 3"))
"Module(
    body=[
        Expr(
            value=BinOp(
                left=BinOp(
                    left=Num(n=1), 
                    op=Add(), 
                    right=Num(n=2)
                ), 
                op=Mult(), 
                right=Num(n=3)
            )
        )
    ]
)"

BinOp op = Mult()表示乘法運(yùn)算,與*相對應(yīng);
BinOp op = Add()表示加法運(yùn)算,與+相對應(yīng);
Num n = 1既為數(shù)值1。

再窺視一下JavaScript的語法樹

在語法復(fù)雜的語言中,語法樹是包含很多細(xì)節(jié)的語法結(jié)果表達(dá)式,我們需要靠語法樹把這種形式以更簡潔的形式表達(dá)出來。

Javascript 有不少工具可以把代碼構(gòu)造出清晰的語法樹,比如 esprima、v8、SpiderMonkey、UglifyJS、AST explorer等。

這里,我使用「esprima」來探討一下JavaScript運(yùn)算(1 + 2) * 3的語法樹。

javascript code:

(1 + 2)* 3;

ast for json:

{
    "type": "Program",
    "body": [
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "BinaryExpression",
                "operator": "*",
                "left": {
                    "type": "BinaryExpression",
                    "operator": "+",
                    "left": {
                        "type": "Literal",
                        "value": 1,
                        "raw": "1"
                    },
                    "right": {
                        "type": "Literal",
                        "value": 2,
                        "raw": "2"
                    }
                },
                "right": {
                    "type": "Literal",
                    "value": 3,
                    "raw": "3"
                }
            }
        }
    ],
    "sourceType": "script"
}

body表示程序體,而程序體中包含了一則表達(dá)式ExpressionStatement, 表達(dá)式體里包含了操作符 *,以及左右兩邊表達(dá)式,其中右邊是數(shù)字3,而左邊表達(dá)式還包含一層表達(dá)式,里面是一個+ 操作符,以及左右兩邊分別為12的數(shù)字。

如果還沒有看懂,你可以到這里看一下這段代碼所生成的語法樹:AST for (1 + 2)* 3;*%203%0A)

我們可以利用語法樹做些什么?

看到這里你可能會問,知道語法是又有什么用呢?跟我日常編寫代碼貌似半毛錢關(guān)系都沒有。其實(shí)語法樹還是很有用的,想一下如果想做「語法高亮」、「關(guān)鍵字匹配」、「作用域判斷」、以及「代碼壓縮」等等,都是最好把代碼解構(gòu)成語法樹之后再去各種操作,當(dāng)然僅僅解構(gòu)還不夠,還需要提供各種函數(shù)去遍歷與修改語法樹。

另一方面,去研究、去探討計(jì)算機(jī)真實(shí)的世界不是一個很精彩很刺激的過程么?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/78917.html

相關(guān)文章

  • JavaScript:上下文相關(guān)

    摘要:在執(zhí)行上下文棧中,全局執(zhí)行上下文處于棧底,頂部為當(dāng)前的執(zhí)行上下文??梢园阉械某绦驁?zhí)行看作一個執(zhí)行上下文棧,棧的頂部是正在激活的上下文。 前言 ??本文內(nèi)容主要涵蓋了執(zhí)行上下文棧、執(zhí)行上下文、變量對象、函數(shù)變量提升等內(nèi)容。 ??眾所周知,JavaScript是單線程編程語言,同一時間只能做一件事情,程序執(zhí)行順序由上而下,程序的執(zhí)行主要依托JavaScript引擎,JavaScript引...

    Michael_Ding 評論0 收藏0
  • 常見react面試題匯總(適合中級前端)

    摘要:但在中會有些不同,包含表單元素的組件將會在中追蹤輸入的值,并且每次調(diào)用回調(diào)函數(shù)時,如會更新,重新渲染組件。在構(gòu)造函數(shù)中調(diào)用的目的是什么在被調(diào)用之前,子類是不能使用的,在中,子類必須在中調(diào)用。將使用單個事件監(jiān)聽器監(jiān)聽頂層的所有事件。 已經(jīng)開源 地址:https://github.com/nanhupatar...關(guān)注我們團(tuán)隊(duì):showImg(https://segmentfault.co...

    leone 評論0 收藏0
  • 何為你的 Vue 項(xiàng)目添加配置 Stylelint

    摘要:如何為你的項(xiàng)目添加配置如何為你的項(xiàng)目添加配置現(xiàn)在已經(jīng)是年了,網(wǎng)上許多教程和分享帖都已經(jīng)過期,照著他們的步驟來會踩一些坑,如已經(jīng)不再維護(hù),以及之后文件只剩下部分等。如有疑問或授權(quán)協(xié)商請與我聯(lián)系。如何為你的 Vue 項(xiàng)目添加配置 Stylelint 現(xiàn)在已經(jīng)是 9102 年了,網(wǎng)上許多教程和分享帖都已經(jīng)過期,照著他們的步驟來會踩一些坑,如 stylelint-processor-html 已經(jīng)不...

    番茄西紅柿 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<