跳到主要内容

什么是抽象语法树?

信息

在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。 它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。

为什么我们需要抽象语法树?

前文中我们提到,Babel的职责是将一种语法转换为另一种语法,比如ES6的语法转换为ES5的语法,Babel是如何做到的呢?

比如下面的这么一段代码:

const count = 1;

如果我们要将ES6语法中的const替换为ES5语法中的var,那么应该怎么去做?

我们可以通过正则表达式去匹配const,然后将其替换为var

但是通过正则去实现,会遇到一个问题,就是我们无法识别const的作用域,比如下面的这段代码:

const count = 1;

if (true) {
const count = 2;
}

console.log(count); // 这里会打印出 1

因为const是有块级作用域的概念的,所以如果我们使用正则表达式去匹配const,那么转换后的代码如下:

var count = 1;

if (true) {
var count = 2;
}

console.log(count); // 这里会打印出 2

我们就会将const count = 2也替换为var count = 2,这样就会导致count的值变为2,而不是1。

所以我们需要一种更加智能的方式去识别const,这就是抽象语法树。

而如何将js代码转换为抽象语法树,并且要以什么样的规则去进行转化,我们在@babel/parser中就可以找到答案。

因为我们完全可以将转换的工作交给Babel进行处理,而我们需要关心的事情就是如何去使用Babel提供了下面的几个库,让我们能够操作抽象语法树,写出自己的Babel插件。

  • @babel/parser:将js代码转换为抽象语法树
  • @babel/traverse:遍历抽象语法树
  • @babel/types:操作抽象语法树
  • @babel/generator:将抽象语法树转换为js代码
  • @babel/template:将字符串转换为抽象语法树
  • @babel/code-frame:生成错误信息
  • @babel/helper-*:一些辅助方法
  • @babel/highlight:高亮代码
  • @babel/helper-plugin-utils:一些辅助方法
  • @babel/core:Babel的核心库
  • @babel/preset-env:Babel的预设库
  • @babel/plugin-*:Babel的插件库
  • @babel/cli:Babel的命令行工具
  • @babel/register:Babel的注册库
  • @babel/polyfill:Babel的垫片库
  • @babel/runtime:Babel的运行时库

在后面的文章中,我们会一一介绍这几个库的使用方法。

当你了解了这几个库的使用方法后,你就可以写出自己的Babel插件了。