ast是什么
AST(Abstract Syntax Tree,抽象语法树)还原是指将经过解析或转换后的抽象语法树结构重新转换成原始的源代码文本。这个过程与代码解析器或编译器中的词法分析、语法分析相反,是逆向生成源代码的过程。
在编程和开发工具中,AST通常用于静态分析、重构、格式化、优化以及代码生成等场景。当对源代码进行修改、优化或分析后,如果需要保持原有的可读性及结构,就需要通过某种方式将修改后的AST转换回人类可读的形式,也就是还原为标准的源代码。
例如,在JavaScript生态中,一些工具如Babel、Prettier或者专门处理AST的库会先将源代码解析成AST,然后对AST进行遍历、修改或操作,最后再利用内置的或自定义的代码生成器,根据AST结构还原出新的合法且格式化的源代码文件。
目标
假设我们要将
var a=2+1;
var b=111+333+444+555;
还原成
var a = 3;
var b = 1443;
安装
npm install @babel/core --save-dev
打开
https://astexplorer.net/
将我们的代码复制进去
开始编写我们的ast代码
// 引入Babel相关模块,用于解析、遍历、生成和判断AST节点类型
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const generator = require("@babel/generator").default;
// 定义JavaScript代码字符串
let jscode = `
var a=2+1;
var b=111+333+444+555;
`;
// 使用Babel解析器将JavaScript代码转换为抽象语法树(AST)
let ast = parser.parse(jscode);
// 定义一个visitor对象,用于处理二元表达式(加法运算)的退出阶段
const combinBin = {
// 当遇到二元表达式时执行此方法
"BinaryExpression": {
exit(path) {
// 解构当前二元表达式节点,获取左右操作数和运算符
let { left, operator, right } = path.node;
// 检查左操作数和右操作数是否都是数字字面量,并且运算符为'+'
if (types.isNumericLiteral(left) && operator === '+' && types.isNumericLiteral(right)) {
// 将两个数字相加得到新的值
let newValue = left.value + right.value;
// 创建一个新的数字字面量节点来替换原有的二元表达式节点
let newNode = types.NumericLiteral(newValue);
// 替换当前路径下的AST节点
path.replaceWith(newNode);
}
}
}
};
// 遍历AST,应用自定义的visitor规则进行处理
traverse(ast, combinBin, opt={});
// 使用Babel生成器将修改后的AST转换回JavaScript代码字符串
let { code } = generator(ast);
// 输出优化后的JavaScript代码
console.log(code);
输出结果为