ast语法树初探
创始人
2024-03-31 07:31:50

前端开发中,使用了很多工具,譬如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.

也就是说,抽象语法树,是通过编程语言编写的代码的抽象语法结构。

用通俗的话讲,我们所使用的编程语言是一门对人类友好的语言,但是对于程序分析来讲,并不友好。因此,需要将编程语言转译成对程序分析友好的语言。

太干了,来点配菜。

我们结合编译过程,来说明抽象语法树的作用。

如下图所示,一般的编译过程分为六个过程。

 那么在语法分析阶段,就是要将词法分析阶段得到的分词结果整合成一棵语法树。简单举个例子:

代码:

1

2

3

4

function foo(a) {

    let b = a + 3;

    return b;

}

将这个函数转成抽象语法树,其核心部分如下图所示:

blockstatement 块级作用域。

VariableDecalaration 变量声明

VariableDecalarator 变量声明器

Returnstatement 返回语句

 在转成语法树之后,就可以对语句进行语法检查或进行修改了。

二、 语法树的应用

前面提到,可以通过对语法树分析来进行语法检查,有没有很熟悉? 有没有想到我们日常写代码过程中用到的eslint 插件、括号高亮插件等。 没有错,他们就是通过对ast 抽象语法树进行分析,来达成语法检查和高亮目的。

话不多说,看图。

 这是一个ast 在我们开发流程中的一个应用总结。

编写代码:我们用 vue的 模板语法去定义一些功能,而这些模板语法最后都要通过对 ast 进行分析最终转为原生 html 和原生 js。

babel 、webpack 和 ast 的关系:

开发过程中,我们使用了大量处于提案阶段的 es6 的 语法,譬如装饰器、箭头函数、模板字符串等,而这些语法,实际上浏览器本身并不支持。因此,需要将其转成 浏览器支持的 es5 代码。这个es 降级的过程就是通过 babel 完成的,而 babel 的核心也就是通过对 ast 进行更改,从而实现 es 语法降级。

webpack 作为模块化开发的主力军,在打包阶段,也是通过对语法树进行分析,最终打包成一个文件上传到服务器上去的。

浏览器执行代码和 ast 的关系:

如图中所示,浏览器执行js 代码的过程和我们上面所阐述的编译的六个阶段是极其一致的。

综上所述,语法树和我们开发的整个过程都是息息相关的。

认识到了语法树在开发过程中的重要性。 接下来,我们通过 babel 的核心库 来简单模拟 es6 转 es5 的过程。

转译过程大致可以分为三步:

  1. 生成语法树
  2. 语法树遍历,更改
  3. 再次遍历语法树,生成新的代码。

通过库 esprima 生成语法树, 通过库 estraverse 遍历语法树并进行语法更改, 通过库 escodegen 遍历语法树,并生成新的代码。 

三、 语法树的生成

语法树生成使用的库是 esprima。

我们先通过一个简单的es6 例子来说明。

es6 通过 let 关键字进行变量声明,从而实现块级作用域。那么转成 es 5 的话只能是 ‘var’。即,代码 ”let a = 15; “ 转变为 ”var a = 15;“。

首先,导入所使用的几个库(库的地址在本文末尾。)并定义字符串。

1

2

3

4

const prima = require('esprima');

const codegen = require('escodegen');

const traverse = require('estraverse');

var  code2 = 'let a = 2';

我们知道,如果要转成语法树,首先要进行词法分析,通过调用esprima 下的 tokenize函数(console.log(prima.tokenize(code2)))可以查看其生成的token。也可以通过可视化工具esprima 可视化查看词法分析结果。

从图中可以看出,esprima 对字符串中的每一个此进行解析,并赋予相应的 type。

在词法解析结束后,再进行语法解析形成 ast 树,可以通过命令行

1

console.log(prima.parseScript(code2));

查看其 ast 的结果,也可以通过 ast 可视化工具 查看其结果。这里展示通过 ast 可视化工具的结果:

 

es6 语法树:     

es5语法树:

 对比这两棵语法树,我们可以看出,其唯一的区别在于,变量声明下,其 kind 节点的值。 那么,接下来,在遍历语法树的时候,我们只要对 node 下的 kind 节点进行变更就可以完成语法转变了。

四、语法树的遍历和更改

我们可以通过  estraverse下的 traverse 函数进行语法树遍历并进行相应更改。

1

2

3

4

5

6

7

8

9

const ast2 = prima.parseScript(code2);

traverse.traverse(ast2, {

    enter(node) {

        if(node.kind === 'let') {

            node.kind = 'var';

        }

    },

});

五、生成 es5 代码

我们通过 escodegen 下的 generate 函数生成 新的es5 代码:

1

2

3

let code2_es5 = codegen.generate(ast2);

console.log(code2_es5);

//'var a = 2;'

写到这里,基本上对 ast 的 what、why、how 进行了一个基本的介绍。 但美中不足的是,上面对于语法树的解析只是利用库函数进行的。接下来,给大家介绍一些 ast 相关的小知识,并尝试带大家,读一读这些函数的源代码。

六、AST 小知识

js 解析器有哪些?我们所使用的工具内核是什么?

常用的 js 解析器有:

esprima: https://github.com/jquery/esprima

acorn:https://github.com/acornjs/acorn

acorn 的诞生晚于 esprima,期因是 esprima 转换速度太慢。

而 babel 目前所用的解析器 fork 自 acorn。webpack 的核心 parser 也是 acorn。而 eslint 作为一个可配置的代码规范检查工具,可以任意选择定义解析器来使用。

而不管是那个解析器,他们解析得到的 ast 树都符合ast 规则:https://github.com/estree/estree

规则起源:

在v8引擎之前,最早js引擎是SpiderMonkey,第一个版本由js作者Brendan Eich设计,后交给Mozilla组织维护。js引擎在执行js文件时,都会先将js代码转换成抽象语法树(AST)。有一天,一位Mozilla工程师在FireFox中公开了这个将代码转成AST的解析器Api,也就是Parser_API,后来被人整理到github项目estree,慢慢的成了业界的规范。

七、 源码解读

待填坑

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...