当前位置:   article > 正文

AST 抽象语法树_ast语法树

ast语法树

AST 是什么

抽象语法树 (Abstract Syntax Tree),简称 AST,它是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

AST 有什么用

AST 运用广泛,比如:

  • 编辑器的错误提示、代码格式化、代码高亮、代码自动补全;
  • elint、pretiier 对代码错误或风格的检查;
  • webpack 通过 babel 转译 javascript 语法;
    并且如果你想了解 js 编译执行的原理,那么你就得了解 AST。

AST 如何生成

s 执行的第一步是读取 js 文件中的字符流,然后通过词法分析生成 token,之后再通过语法分析( Parser )生成 AST,最后生成机器码执行。
整个解析过程主要分为以下两个步骤:

  • 分词:将整个代码字符串分割成最小语法单元数组
  • 语法分析:在分词基础上建立分析语法单元之间的关系
    JS Parser 是 js 语法解析器,它可以将 js 源码转成 AST,常见的 Parser 有 esprima、traceur、acorn、shift 等

词法分析

词法分析,也称之为扫描(scanner),简单来说就是调用 next() 方法,一个一个字母的来读取字符,然后与定义好的 JavaScript 关键字符做比较,生成对应的Token。Token 是一个不可分割的最小单元:

例如 var 这三个字符,它只能作为一个整体,语义上不能再被分解,因此它是一个 Token。

词法分析器里,每个关键字是一个 Token ,每个标识符是一个 Token,每个操作符是一个 Token,每个标点符号也都是一个 Token。除此之外,还会过滤掉源程序中的注释和空白字符(换行符、空格、制表符等。
最终,整个代码将被分割进一个tokens列表(或者说一维数组)。

语法分析

语法分析会将词法分析出来的 Token 转化成有语法含义的抽象语法树结构。同时,验证语法,语法如果有错的话,抛出语法错误。
说了这么多我们来看下 javaScript 代码片段转成 AST 之后是什么样的我们拿一行简单的代码来展示

例子 1

const fn = a => a;

在这里插入图片描述
如图从这个 AST 语法树我们就能够很清楚的看出一个代码他的具体含义,并且使用的是什么语法,方法等。
用人话翻译这个图就是:用类型 const 声明变量 fn 指向一个箭头函数表达式,它的参数是 a 函数体也是 a。

例子 2

const fn = a => {
	let i = 1;
  return a + i;
};
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

例子 3

function test(){
  let a = 1;
  console.log(a)
}
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
以上截图均是使用 Acorn 解析。使用 Acorn 的原因是据我了解在 parser 解析中,Acorn 是公认的最快的。并且我们使用的 Webpack 打包工具中 babel 用的也是 Acorn。
上述截图的属性是 AST 的一部分,这个结构包含了很多属性。

  • VariableDeclaration 变量声明
  • VariableDeclarator 变量声明的描述
  • Expression 表达式节点

更多属性展示:

  1. 可以去 AST explorer 可以在线看到不同的 parser 解析 js 代码后得到的 AST。
  2. github 上看所有的 ESTree ESTree
  3. 关于属性介绍的文档 抽象语法树AST介绍

实战 AST 的运用

题目

通过上面介绍的 console.log AST,下面我们就来完成一个在调用 console.log(xx) 时候给前面加一个函数名,这样用户在打印时候能改方便看到是哪个函数调用的。

// 源代码
function getData() {
  console.log("data")
}
// --------------------
// 转化后代码
function getData() {
  console.log("getData", "data");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

介绍
首先介绍下我们需要使用的工具 Babel

  • @babel/parser : 将 js 代码 ------->>> AST 抽象语法树;
  • @babel/traverse 对 AST 节点进行递归遍历;
  • @babel/types 对具体的 AST 节点进行进行修改;
  • @babel/generator : AST 抽象语法树 ------->>> 新的 js 代码;
    为什么使用 babel ? 主要是比较好用(只对这个比较熟悉
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/597722
推荐阅读
相关标签