Javascript抽象语法树上篇(基础篇)

一、基础

为什么要了解抽象语法树

日常工作中,我们会碰到 js 代码解析的场景,比如分析代码中 require 了哪些包,有些什么关键 API 调用,大部分情况使用正则表达式来处理,可一旦场景复杂,或者依赖于代码上下文时,正则就很难处理了,这时候就要用到抽象语法树。常见的 uglify、eslint、babel、webpack 等等都是基于抽象语法树来处理的,如此强大,有必要好好了解一下。

什么是抽象语法树

抽象语法树即:Abstract Syntax Tree。简称 AST,见下图。

  1. 图中 code 先经过 parse 转换成一个树状数据结构
  2. 接着对树中节点进行转换,图中将叶子节点对换位置
  3. 将树状结构通过 generate 再生成 code

图中树状数据结构即 AST,从这个过程可以看到将代码转成 AST 后,通过操作节点来改变代码。

如何获得抽象语法树

获得抽象语法树的过程为:代码 => 词法分析 => 语法分析 => AST词法分析:把字符串形式的代码转换为令牌(tokens)流。语法分析:把一个令牌流转换成 AST 的形式。这个阶段会使用令牌中的信息把它们转换成一个 AST 的表述结构,这样更易于后续的操作。

如下图,代码为一个简单的函数声明。词法分析阶段,将代码作为字符串输入获得关键词,图中 functionsquare(){}等都被识别为关键词 (稍微回忆下编译原理,字符挨个入栈,符合一定规则即出栈)。语法分析阶段,对关键词的组合形成一个个节点,如 n*n 这 3 个关键词组合成 二元表达式,关键词 return 与二元表达式组合成 return语句。最后组合成一个 函数声明语句

二、规范

如何获得 AST 已经简单介绍了,那 AST 最终应该以什么样的数据结构存在呢,先看看上述函数声明的 AST 结构

那解析的依据是什么,为什么要以上图的结构出现,业界已经有了一套成熟的规范。

规范起源