当前位置:   article > 正文

抽象语法树(AST)

令牌嵌入 抽象语法树

 

AST描述

  在计算机科学中,抽象语法树(AST)或语法树是用编程语言编写的源代码的抽象语法结构的树表示。树的每个节点表示在源代码中出现的构造。语法是“抽象的”,因为它不代表真实语法中出现的每个细节,而只是结构,内容相关的细节。例如,分组括号 在树结构中是隐式的,并且可以通过具有三个分支的单个节点来表示类似于if-condition-then表达式的句法结构。

  这将抽象语法树与传统上指定的解析树区分开来,这些语法树通常由解析器在源代码转换和编译过程中构建。一旦构建,通过后续处理(例如,上下文分析)将附加信息添加到AST 。

  抽象语法树也用于程序分析和程序转换系统。

  参考:[维基百科](https://en.wikipedia.org/wiki/Abstract_syntax_tree)

解析器Parser

  JavaScript Parser是把js源码转化为抽象语法树的解析器,一般分为词法分析、语法分析及代码生成或执行。

词法分析

  词法分析阶段会把字符串形式的代码转换为令牌(Tokens)流。可将令牌看作是一个扁平的语法片段数组。

  1. var answer = 6 * 7;
  2. //Tokens
  3. [
  4. {
  5. "type": "Keyword",
  6. "value": "var",
  7. "range": [
  8. 34,
  9. 37
  10. ],
  11. "loc": {
  12. "start": {
  13. "line": 2,
  14. "column": 0
  15. },
  16. "end": {
  17. "line": 2,
  18. "column": 3
  19. }
  20. }
  21. },
  22. {
  23. "type": "Identifier",
  24. "value": "answer",
  25. "range": [
  26. 38,
  27. 44
  28. ],
  29. "loc": {
  30. "start": {
  31. "line": 2,
  32. "column": 4
  33. },
  34. "end": {
  35. "line": 2,
  36. "column": 10
  37. }
  38. }
  39. },
  40. {
  41. "type": "Punctuator",
  42. "value": "=",
  43. "range": [
  44. 45,
  45. 46
  46. ],
  47. "loc": {
  48. "start": {
  49. "line": 2,
  50. "column": 11
  51. },
  52. "end": {
  53. "line": 2,
  54. "column": 12
  55. }
  56. }
  57. },
  58. {
  59. "type": "Numeric",
  60. "value": "6",
  61. "range": [
  62. 47,
  63. 48
  64. ],
  65. "loc": {
  66. "start": {
  67. "line": 2,
  68. "column": 13
  69. },
  70. "end": {
  71. "line": 2,
  72. "column": 14
  73. }
  74. }
  75. },
  76. {
  77. "type": "Punctuator",
  78. "value": "*",
  79. "range": [
  80. 49,
  81. 50
  82. ],
  83. "loc": {
  84. "start": {
  85. "line": 2,
  86. "column": 15
  87. },
  88. "end": {
  89. "line": 2,
  90. "column": 16
  91. }
  92. }
  93. },
  94. {
  95. "type": "Numeric",
  96. "value": "7",
  97. "range": [
  98. 51,
  99. 52
  100. ],
  101. "loc": {
  102. "start": {
  103. "line": 2,
  104. "column": 17
  105. },
  106. "end": {
  107. "line": 2,
  108. "column": 18
  109. }
  110. }
  111. },
  112. {
  113. "type": "Punctuator",
  114. "value": ";",
  115. "range": [
  116. 52,
  117. 53
  118. ],
  119. "loc": {
  120. "start": {
  121. "line": 2,
  122. "column": 18
  123. },
  124. "end": {
  125. "line": 2,
  126. "column": 19
  127. }
  128. }
  129. }
  130. ]

  

语法分析  

  语法分析阶段会把一个令牌流转换成抽象语法树(AST)的形式,这个阶段会使用令牌中的信息把它们转换成一个AST的树结构。

// 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
        }
    }
}
View Code

常见的AST node类型

  AST树每一层结构也被叫做节点(Node)。一个AST可以由单一的节点或是成百上千个节点够成,通过组合在一起来描述静态分析的程序语法(静态分析是在不需要执行代码的前提下对代码进行分析的处理过程 (执行代码的同时进行代码分析即是动态分析)。 静态分析的目的是多种多样的, 它可用于语法检查,编译,代码高亮,代码转换,优化,压缩等等场景。)。

 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
 
 

使用esprima生成抽象语法树流程

  以上生成的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重新生成源码。

常用的JavaScript Parser

  [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,欢迎使用~~~

转载于:https://www.cnblogs.com/aaron-pan/p/10572953.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/597690
推荐阅读
相关标签
  

闽ICP备14008679号