JesseZhao1990 / blog

learing summary
MIT License
62 stars 7 forks source link

抽象语法树(Abstract Syntax Tree) #108

Open JesseZhao1990 opened 6 years ago

JesseZhao1990 commented 6 years ago

一般来说,程序中的一段源代码在执行之前会经历下面三个步骤

  1. 分词/词法分析 这个过程会将由字符组成的字符串分解成有意义的代码快,这些代码块被称为词法单元。例如 var a = 4;会被分解成 var、a、=、4、;
  2. 解析/语法分析 这个过程是将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树,这个树就叫“抽象语法树”(AST)。全称 Abstract Syntax Tree。
  3. 代码生成 将AST转换成可执行代码的过程称为代码生成。抛开具体细节不讲,简单来说就是有某种方法可以将var a= 4; 的AST转化为一组机器指令,用来创建一个叫做a的变量,并将一个值储存在a中。

可能以上的这些听起来有些云里雾里。因为在平时写代码的时候,不关注这些也能写代码。但是多了解一些,就多一扇看到未知世界的窗口。你肯定使用过前端的很多工具插件,webpack,eslint啥的。你知道这些工具的核心都是通过抽象语法树这个概念来实现对代码的检查,分析,转换的吗?

抽象语法树的定义

In computer science, an abstract syntax tree (AST), or just syntax tree, is a tree representation of the abstract syntactic structure of source code written in a programming language.

翻译一下就是: 在计算机科学中,一个抽象语法树,或者词法树,是一个树,这个树表示或者说抽象出了编程语言的源代码的结构。

这个工具能在线可视化解析出一段代码的抽象语法树,可能能帮助你理解

这个可以进一步看更详尽的信息

下面举一个上边工具中的demo,看看js在执行之前的三步中的前两步都是具体的干了啥。

            var a = 42;
            var b = 5;
            function addA(d) {
            return a + d;
            }
            var c = addA(2) + b;

第一步,词法分析,以上代码词法分析之后长成如下图所示 image 第二步,语法分析,生产抽象语法树,生成的抽象语法树如下图所示 image

JavaScript Parser

JavaScript Parser 把js源码转化为抽象语法树的解析器。前边我们也说了。浏览器在执行js之前会把js源码通过解析器转化为抽象语法树,再进一步转化为字节码甚至是机器码。

常用的JavaScript Parser有:

使用Esprima生成并使用抽象语法树。

  1. 通过esprima将一个空函数的源码生成一棵AST树
  2. 通过estraverse遍历并更新AST树
  3. 通过escodegen将AST重新生成源码

抽象语法树的用途

其实从以上的三个工具,也可大致猜测到抽象语法树的一般用途了。大致分为几类吧

  1. IDE插件,如代码语法检查,代码风格检查,代码的格式化,代码高亮,代码错误等等之类的
  2. 代码的混淆压缩,如UglifyJS2等
  3. 转换代码的工具。如webpack,rollup,各种代码规范之间的转换,ts,jsx, vue中的template等转换为原生js