在計算機科學中,抽象語法樹(AST)或語法樹是用編程語言編寫的源代碼的抽象語法結構的樹表示。樹的每一個節點表示在源代碼中出現的構造。語法是「抽象的」,由於它不表明真實語法中出現的每一個細節,而只是結構,內容相關的細節。例如,分組括號 在樹結構中是隱式的,而且能夠經過具備三個分支的單個節點來表示相似於if-condition-then表達式的句法結構。javascript
這將抽象語法樹與傳統上指定的解析樹區分開來,這些語法樹一般由解析器在源代碼轉換和編譯過程當中構建。一旦構建,經過後續處理(例如,上下文分析)將附加信息添加到AST 。html
抽象語法樹也用於程序分析和程序轉換系統。java
參考:[維基百科](https://en.wikipedia.org/wiki/Abstract_syntax_tree)node
JavaScript Parser是把js源碼轉化爲抽象語法樹的解析器,通常分爲詞法分析、語法分析及代碼生成或執行。jquery
詞法分析階段會把字符串形式的代碼轉換爲令牌(Tokens)流。可將令牌看做是一個扁平的語法片斷數組。git
var answer = 6 * 7; //Tokens [ { "type": "Keyword", "value": "var", "range": [ 34, 37 ], "loc": { "start": { "line": 2, "column": 0 }, "end": { "line": 2, "column": 3 } } }, { "type": "Identifier", "value": "answer", "range": [ 38, 44 ], "loc": { "start": { "line": 2, "column": 4 }, "end": { "line": 2, "column": 10 } } }, { "type": "Punctuator", "value": "=", "range": [ 45, 46 ], "loc": { "start": { "line": 2, "column": 11 }, "end": { "line": 2, "column": 12 } } }, { "type": "Numeric", "value": "6", "range": [ 47, 48 ], "loc": { "start": { "line": 2, "column": 13 }, "end": { "line": 2, "column": 14 } } }, { "type": "Punctuator", "value": "*", "range": [ 49, 50 ], "loc": { "start": { "line": 2, "column": 15 }, "end": { "line": 2, "column": 16 } } }, { "type": "Numeric", "value": "7", "range": [ 51, 52 ], "loc": { "start": { "line": 2, "column": 17 }, "end": { "line": 2, "column": 18 } } }, { "type": "Punctuator", "value": ";", "range": [ 52, 53 ], "loc": { "start": { "line": 2, "column": 18 }, "end": { "line": 2, "column": 19 } } } ]
語法分析階段會把一個令牌流轉換成抽象語法樹(AST)的形式,這個階段會使用令牌中的信息把它們轉換成一個AST的樹結構。github
// Life, Universe, and Everything var answer = 6 * 7; // Syntax { "type": "Program", "body": [ { "type": "VariableDeclaration", "declarations": [ { "type": "VariableDeclarator", "id": { "type": "Identifier", "name": "answer", "range": [ 38, 44 ], "loc": { "start": { "line": 2, "column": 4 }, "end": { "line": 2, "column": 10 } } }, "init": { "type": "BinaryExpression", "operator": "*", "left": { "type": "Literal", "value": 6, "raw": "6", "range": [ 47, 48 ], "loc": { "start": { "line": 2, "column": 13 }, "end": { "line": 2, "column": 14 } } }, "right": { "type": "Literal", "value": 7, "raw": "7", "range": [ 51, 52 ], "loc": { "start": { "line": 2, "column": 17 }, "end": { "line": 2, "column": 18 } } }, "range": [ 47, 52 ], "loc": { "start": { "line": 2, "column": 13 }, "end": { "line": 2, "column": 18 } } }, "range": [ 38, 52 ], "loc": { "start": { "line": 2, "column": 4 }, "end": { "line": 2, "column": 18 } } } ], "kind": "var", "range": [ 34, 53 ], "loc": { "start": { "line": 2, "column": 0 }, "end": { "line": 2, "column": 19 } }, "leadingComments": [ { "type": "Line", "value": " Life, Universe, and Everything", "range": [ 0, 33 ], "loc": { "start": { "line": 1, "column": 0 }, "end": { "line": 1, "column": 33 } } } ] } ], "sourceType": "script", "range": [ 34, 53 ], "loc": { "start": { "line": 2, "column": 0 }, "end": { "line": 2, "column": 19 } } }
AST樹每一層結構也被叫作節點(Node)。一個AST能夠由單一的節點或是成百上千個節點夠成,經過組合在一塊兒來描述靜態分析的程序語法(靜態分析是在不須要執行代碼的前提下對代碼進行分析的處理過程 (執行代碼的同時進行代碼分析便是動態分析)。 靜態分析的目的是多種多樣的, 它可用於語法檢查,編譯,代碼高亮,代碼轉換,優化,壓縮等等場景。)。npm
Node types:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API#Node_objects
編程
babel AST node types:https://github.com/babel/babylon/blob/master/ast/spec.md
以上生成的AST樹可視化工具:[esprima](http://esprima.org/demo/parse.html#)生成,經過[esprima](https://github.com/jquery/esprima)將源碼生成抽象語法樹,並經過[estraverse](https://github.com/estools/estraverse)遍歷並更新AST,最後經過[escodegen](https://github.com/estools/escodegen)將AST從新生成源碼。數組
[Acorn](https://github.com/acornjs/acorn),[Esprima](https://github.com/jquery/esprima),[UglifyJS2](https://github.com/mishoo/UglifyJS2),[Babel(https://github.com/babel/babel)等
最後,根據對抽象語法樹的大概瞭解作了個demo級的將命名函數轉換爲exports函數的npm包:https://www.npmjs.com/package/fn2export,歡迎使用~~~