简述 AST 抽象语法树

简述 AST 抽象语法树

一、概念

AST 全称为 Abstract Syntax Tree,译为抽象语法树。在 JavaScript 中,任何一个对象(变量、函数、表达式等)都可以转化为一个抽象语法树的形式。抽象语法树本质就是一个树形结构的对象。

使用 astexplorer 可以在线将任意对象,表达式转换为 AST 语法树。
在这里插入图片描述
如果到这里你还是不太理解 AST 是什么东西。那么假设你的电脑主板坏掉了。维修人员的修理过程是:先把电脑各个零件拆开,找到坏掉的主板,检查主板是否还可以修好。如果不行,则换一个新的主板,再把电脑一步步重新组装好。那么 AST 就是被拆解的一个个电脑零件。

二、特点

一个对象生成 AST 的关键所在是词法分析和语法分析。
词法分析指的是将对象逐个扫描,获取每一个字母的信息,生成由对象组成的一维数组。

const a = 5;
//词法分析
[{value:'const',type:'keyword'},{value:'a',type:'identifier'}...]

语法分析指的是将有关联的对象整合成树形结构的表达形式。

const a = 5;
//语法分析
{
  "type": "Program",
  "start": 0,
  "end": 12,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 12,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 6,
          "end": 11,
          "id": {
            "type": "Identifier",
            "start": 6,
            "end": 7,
            "name": "a"
          },
          "init": {
            "type": "Literal",
            "start": 10,
            "end": 11,
            "value": 5,
            "raw": "5"
          }
        }
      ],
      "kind": "const"
    }
  ],
  "sourceType": "module"
}

三、用途

常用语各类转义、编译的插件中。比如最典型的 ES6 转换为 ES6 工具 、JSX 语法转换为 JavaScript 语法的 babel,代码规范工具 ESLint 以及各类 JS/CSS/HTML 压缩工具。

四、案例

现在,我们使用 AST 的概念来拆解一个最简单的函数。

function exp(a){return a}

使用 astexplorer 在线拆解得到结果如下:
在这里插入图片描述

  1. 在最外层的 type、start、end、body、sourceType 中,我们主要看中间 body 部分。把每一个 body 当成一个块来拆解。
  2. 第一个 body(块) 就是 function exp(a) 这段。这是一个 type 为 FunctionDeclaration (函数定义)类型的对象。每一个函数定义的块中都有一个 id 对象。如上所示,它的 id 对象信息中 type 为 Identifier,name 为 exp。它不是表达式,也不是异步。所以 express、generator、async 皆为 false。最后它有一个参数 params 对象集,在该参数对象集中参数名 name 为 a
  3. 再看第二个 body(块) 就是 return a。这是一个 type 为 BlockStatement (块语句)类型的对象。在其内部有一个 type 为 ReturnStatement (返回语句)类型的语句。在返回的 argument 集合中参数名 name 为形参 a
  4. 可以看到上面的拆解中,每一个块都有 type、start、end、body 这几个字段。
    其中 type 表达当前块的类型。比如 FunctionDeclaration 表示函数定义,Identifier 表示标识符、BlockStatement 表示块语句、ReturnStatement 表示返回语句等。
    start 表示该块开始的位置,end 表示该块结束的位置,body 表示子块。
    其他的字段根据块的性质不同有所不同。
发布了263 篇原创文章 · 获赞 2448 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/104161823