1.如何生成AST
生成过程:1.源码--2.词法分析--3.语法分析--4.抽象语法树
1.1、词法分析
词法分析阶段把字符串形式的代码转换为令牌(tokens)流。
从左到右一个字符一个字符地读入源程序,从中识别出一个个“单词”"符号"等
单词 单词 符号 数字 符号 数字 符号
| let | sum | = | 10 | + | 66 | ; |
[
{"type": "word", value: "let"}
{"type": "word", value: "sum"}
{"type": "Punctuator", value: "="}
{"type": "Numeric", value: "10"}
{"type": "Punctuator", value: "+"}
{"type": "Numeric", value: "66""}
{"type": "Punctuator", value: ";"}
]
1.2、语法分析
语法分析阶段会把一个令牌流转换成 AST 的形式。 这个阶段会使用令牌中的信息把它们转换成一个 AST 的表述结构,这样更易于后续的操作。
即:在词法分析的基础上根据当前编程语言的语法,将单词序列组合成各类语法短语
关键字 标识符 赋值运算符 字面量 二元运算符 字面量 结束符号
| let | sum | = | 10 | + | 66 | ; |
[{
"type": "VariableDeclaration",
"content": {
{"type": "kind", value: "let"} // kind 表示是什么类型的声明
{"type": "Identifier", value: "sum"} // Identifier 表示是标识符
{"type": "init", value: "="} // init 表示初始值的表达式
{"type": "Literal", value: "10"} // Literal 表示是一个字面量
{"type": "operator", value: "+"} // operator 表示是一个二元运算符
{"type": "Literal", value: "66""}
{"type": "Punctuator", value: ";"}
}
}]
1.3生成抽象语法树
let tree = {
"type": "Program",
"start": 0,
"end": 18,
"body": [
{
"type": "VariableDeclaration",
"kind": "let",
"start": 0,
"end": 18,
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 17,
"id": {
"type": "Identifier",
"start": 4,
"end": 7,
"name": "sum"
},
"init": {
"type": "BinaryExpression",
"start": 10,
"end": 17,
"left": {
"type": "Literal",
"start": 10,
"end": 12,
"value": 10,
"raw": "10"
},
"operator": "+",
"right": {
"type": "Literal",
"start": 15,
"end": 17,
"value": 66,
"raw": "66"
}
}
}
],
}
]
};
2. 应用
babel转换为可执行代码
2.1. Babel 使用 @babel/parser 解析代码,输入的 js 代码字符串根据 ESTree 规范生成 AST(抽象语法树)。Babel 使用的解析器是babylon。
2.2. 将AST转化为可执行代码
Babel提供了@babel/traverse(遍历)方法维护这AST树的整体状态,并且可完成对其的替换,删除或者增加节点,这个方法的参数为原始AST和自定义的转换规则,返回结果为转换后的AST。