前端-编译原理 从babel学习抽象语法树

我心飞翔 分类:javascript

babel是一个JavaScript语法转换器,它可以利用各种插件将ES6+TypeScriptjsxtsx等各种语法转换成浏览器可执行的代码。本文主要通过探索babel背后的原理来学习抽象语法树(AST)。

babel的工作流程

babel的工作流程大致分为以下三个阶段:

  1. 解析:解析阶段主要做两件事情,词法分析语法分析
  2. 转换:代码经过解析后会生成抽象语法树(AST),转换阶段就是对生成的AST进行遍历,通过遍历AST的节点可以对AST进行节点的新增、修改和删除操作。babel的插件就是工作在这个阶段。
  3. 生成:生成阶段就是对转换后的AST变成最终浏览器可执行的字符串代码。

image.png

词法分析

词法分析是babel解析代码的第一步,这一步主要是将我们编写的代码变成token流,token流使用数组记录了代码中字符的信息。
比如我们书写了下面一段代码:

   a + b 
 

则该段代码的token流数组结构如下:

[
  { type: { ... }, value: "a", start: 0, end: 1, loc: { ... } },
  { type: { ... }, value: "+", start: 2, end: 3, loc: { ... } },
  { type: { ... }, value: "b", start: 4, end: 5, loc: { ... } },
]
 

语法分析

语法分析会将token流转换成抽象语法树(AST),这个阶段也是本文讨论的重点。

那么babel生成的抽象语法树(AST)到底是怎样的一个结构呢?
我们通过AST Explorer来学习抽象语法树。从下图中可以看到抽象语法树是一个js对象对象基本结构如下,在这个对象中有typecommentssourceTypebody等属性。

  • type是一个非常重要的属性表示抽象语法树节点的类型。更多节点类型参考这里
  • body存放的是子节点

image.png

接下来通过举例变量声明函数来探究一下抽象语法树。

变量声明

当我们输入下面一段代码,声明一个变量,看一看抽象语法树有什么变化。

var a=1;
 

此时AST变成了如下结构:
可以看到在属性body的数组中新增了一个VariableDeclaration类型的对象,对象属性type的值为VariableDeclaration表示这是一个变量声明的节点。这个节点对象的属性描述了这条声明语句的信息。

image.png

函数声明

接下来我们在上面代码的基础上再声明一个函数名为test的函数。

var a=1;

function test(){
  var b=2;
  var c=b+1;
  return c;
}
 

此时AST的body中多了一个FunctionDeclaration类型的对象。

image.png

展开这个FunctionDeclaration类型的对象如下图,这个对象中也有一个body的属性里面记录了,我们在函数中声明的两个变量和函数的返回值。

image.png

总结

babel通过不同对象类型来定义不同的AST节点。各个节点组成了代码的整个抽象语法树。对于抽象语法树的学习有利于理解程序的运行原理。也是我们编写babel插件的基础。

参考

github.com/jamiebuilds…

en.wikipedia.org/wiki/Lexica…

抽象语法树生成工具:astexplorer.net/

回复

我来回复
  • 暂无回复内容