-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 149 题:babel 怎么把字符串解析成 AST,是怎么进行词法/语法分析的? #315
Labels
Comments
大致分为下面四步:
具体见下方链接文件的代码: |
Babel定义
Babel概述
Babel 中重要的对象Vistorbabel 在处理一个节点时,是以访问者的形式获取节点的信息,并进行相关的操作,这种操作是通过visitor对象实现的。 在 visitor 中定义了处理不同节点的函数。 visitor: {
Program: {
enter(path, state) {
console.log('start processing this module...');
},
exit(path, state) {
console.log('end processing this module!');
}
},
ImportDeclaration:{
enter(path, state) {
console.log('start processing ImportDeclaration...');
// do something
},
exit(path, state) {
console.log('end processing ImportDeclaration!');
// do something
}
}
} AST定义
Javascript 语法的AST(抽象语法树)
转换的抽象语法树:var answer= 6 * 7每一个含有type属性的对象,我们称之为节点,修改是指获取对应的类型并修改改节点的属性即可; {
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "answer"
},
"init": {
"type": "BinaryExpression",
"operator": "*",
"left": {
"type": "Literal",
"value": 6,
"raw": "6"
},
"right": {
"type": "Literal",
"value": 7,
"raw": "7"
}
}
}
],
"kind": "var"
}
],
"sourceType": "script"
} estraverse 遍历和修改ASTconst esprima = require("esprima");
const estraverse = require("estraverse");
let code = "var answer=6 * 7";
// 遍历语法树
estraverse.traverse(esprima.parseScript(code), {
enter(node) {
console.log("enter", node.type);
},
leave(node) {
console.log("leave", node.type);
}
});
escodegen 将 AST 转换成 JSconst esprima = require("esprima");
const estraverse = require("estraverse");
const escodegen= require("escodegen");
let code = "var answer=6 * 7";
let tree=esprima.parseScript(code); // 生成语法树
// 遍历语法树
estraverse.traverse(tree, {
enter(node) {
console.log("enter", node.type);
// 修改变量名
if(node.type==='VariableDeclarator'){
node.id.name='result';
}
},
leave(node) {
console.log("leave", node.type);
}
});
// 编译修改后的语法树;
let compileTreeJS=escodegen.generate(tree);
console.log(compileTreeJS);
通过工具了解抽象语法树在 JavaScript 中的体现以及在 NodeJS 中用于生成、遍历和修改 AST 抽象语法树的核心依赖;让我们有了更加深刻地认识; |
编译原理(第2版) 值得一读 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No description provided.
The text was updated successfully, but these errors were encountered: