抽象语法树(Abstract Syntax Tree)
- webpack 和 Lint 等很多的工具和库的核心都是通过 Abstract Syntax Tree 抽象语法树这个概念来实现对代码的检查、分析等操作的;
- 通过了解抽象语法树这个概念,可以随手编写类似的工具;
抽象语法树用途
- 代码语法的检查、代码风格的检查、代码的格式化、代码的高亮、代码错误提示、代码自动补全等等
- 如 JSLint、JSHint 对代码错误或风格的检查,发现一些潜在的错误;
- IDE 的错误提示、格式化、高亮、自动补全等等;
- 代码混淆压缩
- UglifyJS2 等;
- 优化变更代码,改变代码结构使达到想要的结构
- 代码打包工具 webpack、rollup 等等;
- CommonJS、AMD、CMD、UMD 等代码规范之间的转化;
- CoffeeScript、TypeScript、JSX 等转化为原生 Javascript;
抽象语法树定义
- 在计算机科学中,抽象语法树(abstract syntax tree 或者缩写为 AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码;
- Javascript 的语法是为了给开发者更好的编程而设计的,但是不适合程序的理解。所以需要转化为 AST 来使之更适合程序分析,浏览器编译器一般会把源码转化为 AST 来进行进一步的分析等其他操作;
JavaScript Parser
- JavaScript Parser 把 js 源码转化为抽象语法树的解析器;
- 浏览器会把 js 源码通过解析器转为抽象语法树,再进一步转化为字节码或直接生成机器码;
- 一般来说每个 js 引擎都会有自己的抽象语法树格式,Chrome 的 v8 引擎,firefox 的 SpiderMonkey 引擎等等,MDN 提供了详细 SpiderMonkey AST format 的详细说明,算是业界的标准;
常用的 JavaScript Parser
- esprima
- traceur
- acorn
- shift
esprima
- AST的可视化工具
- 示例代码:
let esprima = require('esprima'); // 把源代码转成抽象语法树 let estraverse = require('estraverse'); // 遍历并更新 AST let escodegen = require('escodegen'); // 将 AST 重新生成源码 let sourceCode = `function ast(){}`; // 源代码就是 ascii 字符串 let ast = esprima.parse(sourceCode); // console.log(ast); /** * 遍历语法树 遍历的方式采用的深度的方式 * 遍历的时候只遍历有 type 属性的节点 * 如果一个节点遍历完成,它同时有儿子和弟弟,如果先遍历弟弟,就是广度,如果先遍历儿子再遍历弟弟就是深度 */ let indent = 0; // 缩进几个空格 const padding = () => " ".repeat(indent); estraverse.traverse(ast, { enter(node) { // 在遍历语法树的时候可以对它进行转换 console.log(padding() + '进入' + node.type); if (node.type === 'FunctionDeclaration') { node.id.name = 'new' + node.id.name; } indent += 4; }, leave(node) { indent -= 4; console.log(padding() + '离开' + node.type); } }); /* 进入Program 进入FunctionDeclaration 进入Identifier 离开Identifier 进入BlockStatement 离开BlockStatement 离开FunctionDeclaration 离开Program */ let targetCode = escodegen.generate(ast); console.log(targetCode); // function newast() {}
打赏作者
您的打赏是我前进的动力
微信
支付宝
虚拟列表
上一篇
评论