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

資訊專欄INFORMATION COLUMN

平庸前端碼農(nóng)之蛻變 — AST

dreamans / 2118人閱讀

摘要:為什么要談抽象語法樹如果你查看目前任何主流的項目中的,會發(fā)現(xiàn)前些年的不計其數(shù)的插件誕生。什么是抽象語法樹估計很多同學(xué)會和圖中的喵一樣,看完這段官方的定義一臉懵逼。它讀取我們的代碼,然后把它們按照預(yù)定的規(guī)則合并成一個個的標(biāo)識。

前言

首先,先說明下該文章是譯文,原文出自《AST for JavaScript developers》。很少花時間特地翻譯一篇文章,咬文嚼字是件很累的事情,實在是這篇寫的太棒了,所以忍不住想和大家一起分享。

該譯文出自我的博客:github.com/CodeLittlePrince/blog/issues/19,我的博客會不定時更新各種類型文章,希望大家支持。

OK,我們直接進(jìn)入正題。

為什么要談AST(抽象語法樹)?

如果你查看目前任何主流的項目中的devDependencies,會發(fā)現(xiàn)前些年的不計其數(shù)的插件誕生。我們歸納一下有:javascript轉(zhuǎn)譯、代碼壓縮、css預(yù)處理器、elint、pretiier,等。有很多js模塊我們不會在生產(chǎn)環(huán)境用到,但是它們在我們的開發(fā)過程中充當(dāng)著重要的角色。所有的上述工具,不管怎樣,都建立在了AST這個巨人的肩膀上。

所有的上述工具,不管怎樣,都建立在了AST這個巨人的肩膀上

我們定一個小目標(biāo),從解釋什么是AST開始,然后到怎么從一般代碼開始去構(gòu)建它。我們將簡單地接觸在AST處理基礎(chǔ)上,一些最流行的使用例子和工具。并且,我計劃談下我的js2flowchart項目,它是一個不錯的利用AST的demo。OK,讓我們開始吧。

什么是AST(抽象語法樹)?

It is a hierarchical program representation that presents source code structure according to the grammar of a programming language, each AST node corresponds to an item of a source code.

估計很多同學(xué)會和圖中的喵一樣,看完這段官方的定義一臉懵逼。OK,我們來看例子:

這很簡化

實際上,正真AST每個節(jié)點會有更多的信息。但是,這是大體思想。從純文純中,我們將得到樹形結(jié)構(gòu)的數(shù)據(jù)。每個條目和樹中的節(jié)點一一對應(yīng)。

那怎么從純文本中得到AST呢?哇哦,我們知道當(dāng)下的編譯器都做了這件事前。那我們就看看一般的編譯器怎么做的就可以了。

想做一款編譯器是個比較消耗發(fā)量的事情,但幸運的是,我們無需貫穿編譯器的所有知識點,最后將高級語言轉(zhuǎn)譯為二進(jìn)制代碼。我們只需要關(guān)注詞法分析和預(yù)發(fā)分析。這兩步是從代碼中生成AST的關(guān)鍵所在。

第一步,詞法分析,也叫做掃描scanner。它讀取我們的代碼,然后把它們按照預(yù)定的規(guī)則合并成一個個的標(biāo)識tokens。同時,它會移除空白符,注釋,等。最后,整個代碼將被分割進(jìn)一個tokens列表(或者說一維數(shù)組)。

當(dāng)詞法分析源代碼的時候,它會一個一個字母地讀取代碼,所以很形象地稱之為掃描-scans;當(dāng)它遇到空格,操作符,或者特殊符號的時候,它會認(rèn)為一個話已經(jīng)完成了。

第二步,語法分析,也解析器。它會將詞法分析出來的數(shù)組轉(zhuǎn)化成樹形的表達(dá)形式。同時,驗證語法,語法如果有錯的話,拋出語法錯誤。

當(dāng)生成樹的時候,解析器會刪除一些沒必要的標(biāo)識tokens(比如不完整的括號),因此AST不是100%與源碼匹配的,但是已經(jīng)能讓我們知道如何處理了。說個題外話,解析器100%覆蓋所有代碼結(jié)構(gòu)生成樹叫做CST(具體語法樹)

我們最終得到的

想要學(xué)習(xí)更多關(guān)于編譯器的知識?
the-super-tiny-compiler,一個賊好的項目。大概200來行代碼,幾乎每行都有注釋。

想要自己創(chuàng)建門編程語言?
LangSandbox,一個更好的項目。它演示了如何創(chuàng)造一門編程語言。當(dāng)然,設(shè)計編程語言這樣的書市面上也一坨坨。所以,這項目更加深入,與the-super-tiny-compiler的項目將Lisp轉(zhuǎn)為C語言不同,這個項目你可以寫一個你自己的語言,并且將它編譯成C語言或者機(jī)器語言,最后運行它。

我能直接用三方庫來生成AST嗎?
當(dāng)然可以!有一坨坨的三方庫可以用。你可以訪問astexplorer,然后挑你喜歡的庫。astexplorer是一個很棒的網(wǎng)站,你可以在線玩轉(zhuǎn)AST,而且除了js,還有很多其它語言的AST庫。

我不得不強(qiáng)調(diào)一款我覺得很棒的三方庫,叫做babylon。

它被用在大名鼎鼎的babel中,也許這也是它之所以這么火的原因。因為有babel項目的支持,我們可以意料到它將與時俱進(jìn),一直支持最新的JS特性,我們可以放心大膽地用,不怕以后JS又出新版導(dǎo)致代碼的大規(guī)模重構(gòu)。另外,它的API也非常的簡單,容易使用。

Ok,現(xiàn)在你知道怎么將代碼生成AST了,讓我們繼續(xù),來看看現(xiàn)實中的用例。

第一個用例,我想談?wù)劥a轉(zhuǎn)化,沒錯,就是那個貨,babel。

Babel is not a ‘tool for having ES6 support’. Well, it is, but it is far not only what it is about.

經(jīng)常把beble和支持es6/7/8聯(lián)系起來,實際上,這也是我們經(jīng)常用它的原因。但是,它僅僅是一組插件中的一個。我們也可以使用它來壓縮代碼,react相關(guān)預(yù)發(fā)轉(zhuǎn)譯(如jsx),flow插件等。

babel是一個javascript編譯器。宏觀來說,它分3個階段運行代碼:解析(parsing),轉(zhuǎn)譯(transforming),生成(generation)。我們可以給babel 一些javascript代碼,它修改代碼然后生成新的代碼返回。那它是怎樣修改代碼的呢?沒錯!它創(chuàng)建了AST,遍歷樹,修改tokens,最后從AST中生成新的代碼。

我們來從下面的demo中看下這個過程:

像我之前提到的,babel使用babylon,所以,首先,我們解析代碼成AST,然后遍歷AST,再反轉(zhuǎn)所有的變量名,最后生成代碼。完成!正如我們看到的,第一步(解析)和第三步(生成)看起來非常常規(guī),我們每次都會做這兩步。所以,babel接管處理了它倆。最后,我們最為關(guān)心的,那就是AST轉(zhuǎn)譯這一步了。

當(dāng)我們開發(fā)babel-plugin的時候,我們只需要描述轉(zhuǎn)化你AST的節(jié)點“visitors”就可以了。

將它加入你的babel插件列表中,設(shè)置你webpack的babel-loader配置或者.babelrc中的plugins即可

You may check out Babel-handbook if you would like to learn more about how to build your first babel-plugin.
如果你想要學(xué)習(xí)怎么創(chuàng)建你的第一個babel-plugin,可以查看Babel-handbook

讓我們繼續(xù),下一個用例,我想提到的是自動代碼重構(gòu)工具,以及神器JSCodeshift。

比如說你想要替換掉所有的老掉牙的匿名函數(shù),把他們變成Lambda表達(dá)式(箭頭函數(shù))。

你的代碼編輯器很可能沒法這么做,因為這并不是簡單地查找替換操作。這時候jscodeshift就登場了。

如果你聽過jscodeshift,你很可能也聽過codemods,一開始挺這兩個詞可能很困惑,不過沒關(guān)系,接下來就解釋。jscodeshift是一個跑codemods的工具。codemod是一段描述AST要轉(zhuǎn)化成什么樣的代碼,這思想和babel的插件如出一轍。

所以,如果你想創(chuàng)建自動把你的代碼從舊的框架遷移到新的框架,這就是一種很乃思的方式。舉個例子,react 16的prop-types重構(gòu)。

有很多不同的codemodes已經(jīng)創(chuàng)建了,你可以保存你需要的,以免手動的修改一坨坨代碼,拿去揮霍吧:
https://github.com/facebook/jscodeshift
https://github.com/reactjs/react-codemod

最后一個用例,我想要提到Prettier,因為可能每個碼農(nóng)都在日常工作中用到它。

Prettier 格式化我們的代碼。它調(diào)整長句,整理空格,括號等。所以它將代碼作為輸入,修改后的代碼作為輸出。聽起來很熟悉是嗎?當(dāng)然!

思路還是一樣。首先,將代碼生成AST。之后依然是處理AST,最后生成代碼。但是,中間過程其實并不像它看起來那么簡單。

同樣,如果你想學(xué)習(xí)更多在美化打印背后理論,這里有一本你可以深入的書 《A prettier printer》。

文章迎來尾聲,我們繼續(xù),今天最后一件事,我想提及的就是我的庫,叫做js2flowchart(4.5 k stars 在 Github)。

顧名思義,它將js代碼轉(zhuǎn)化生成svg流程圖

這是一個很好的例子,因為它向你展現(xiàn)了你,當(dāng)你擁有AST時,可以做任何你想要做的事。把AST轉(zhuǎn)回成字符串代碼并不是必要的,你可以通過它畫一個流程圖,或者其它你想要的東西。

js2flowchart使用場景是什么呢?通過流程圖,你可以解釋你的代碼,或者給你代碼寫文檔;通過可視化的解釋學(xué)習(xí)其他人的代碼;通過簡單的js語法,為每個處理過程簡單的描述創(chuàng)建流程圖。

馬上用最簡單的方式嘗試一下吧,去線上編輯看看 js-code-to-svg-flowchart

你也可以在代碼中使用它,或者通過CLI,你只需要指向你想生成SVG的文件就行。而且,還有VS Code插件(鏈接在項目readme中)

那么,它還能做什么呢?哇哦,我這里就不廢話了,大家有興趣直接看這個項目的文檔吧。

OK,那它是如何工作的呢?

首先,解析代碼成AST,然后,我們遍歷AST并且生成另一顆樹,我稱之為工作流樹。它刪除很多不重要的額tokens,但是將關(guān)鍵塊放在一起,如函數(shù)、循環(huán)、條件等。再之后,我們遍歷工作流樹并且創(chuàng)建形狀樹。每個形狀樹的節(jié)點包含可視化類型、位置、在樹中的連接等信息。最后一步,我們遍歷所有的形狀,生成對應(yīng)的SVG,合并所有的SVG到一個文件中。

結(jié)尾

尋找和篩選資料著實辛苦,希望同學(xué)們可以多多支持!

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

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

相關(guān)文章

  • 統(tǒng)一認(rèn)證 - Apereo CAS 簡介

    摘要:在將臭未臭之前,我們趕緊把其中的統(tǒng)一認(rèn)證這塊過一下。的歷史前面說了是耶魯大學(xué)實驗室的在年出的一個開源系統(tǒng)。這次我們先看看官網(wǎng)出的一幅圖,這張圖片介紹了的組成以及支持的各種協(xié)議,各種特性,不煩看看 為什么要做這個嘗試? 微服之道,方興未艾;農(nóng)之來學(xué)者,蓋已千者! 這句是從《陶山集·太學(xué)案問》瞎改出來的。意思就是微服務(wù)的架構(gòu)理念還在不斷地發(fā)展,現(xiàn)在整個啥都 言必出微服務(wù),差點都到了 沒學(xué)...

    zhunjiee 評論0 收藏0
  • Java很傻,但是IDE很聰明

    摘要:執(zhí)行效率很重要,但是在很多情況下,程序員的效率更重要的,而且語言的執(zhí)行效率是可以發(fā)展的。,但是很牛逼,可以了解一些上的高級語言,比如。很聰明最大的好處,就是足夠成熟,市場占有率高。所以說,很傻,但是很聰明。碼農(nóng)界有很多圣戰(zhàn),。 對于編程 語言來說,什么是生產(chǎn)力?我覺得,更高的抽象層次就是生產(chǎn)力。 執(zhí)行效率很重要,但是在很多情況下,程序員的效率更重要的,而且語言的執(zhí)行效率是可以發(fā)展的。該...

    jeffrey_up 評論0 收藏0
  • 沒有實戰(zhàn)經(jīng)驗?從零敲一個企業(yè)級共享項目前后端!

    摘要:業(yè)務(wù)具體介紹,本系統(tǒng)是一個共享圖書的小程序項目,企業(yè)級,創(chuàng)業(yè)項目。具體業(yè)務(wù)流程類似共享自行車,也有設(shè)計押金月卡季卡等等。以上是單個頁面的實現(xiàn)基本文件目錄。其中還涉及微信支付環(huán)節(jié)。 本博客 貓叔的博客,轉(zhuǎn)載請申明出閱讀本文約3分鐘適讀人群:Java后端、Java初級、小程序前端 本文是兩個GitHub項目的序章,旨在指導(dǎo)初級程序員完成一個企業(yè)級共享項目的前后端代碼實踐,豐富自身的實戰(zhàn)經(jīng)...

    劉明 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<