工作中需要将javascript的if语句描述进行一些规范化,将类似
if(test) value0
else value1
的语句的全部统一成:
if (test)
result = value0;
else
result = value1;
格式的,便于后续处理。
方法之一使用AST替换来完成,主要用到estools提供的javascript解析和代码生成工具。
主要操作如下
1) 安装node.js
2) mkdir convert
cd convert
npm install esprima
npm install estraverse
npm install escodegen
3) 编写AST解析代码,并且查看生成的AST树
var ast = esprima.parse(code);
console.log(JSON.stringify(ast,null,4));
4)编写遍历if语句的代码,如果不符合格式,就改变AST的节点。
ast = estraverse.replace(ast, {
leave: function(node, parent)
{
modifiedNode = node;
if (node.type === 'IfStatement') {
if (node.consequent.type === 'ExpressionStatement')
{
if (node.consequent.expression.type === 'Literal'){
modifiedNode['consequent'] = {
"type": "ExpressionStatement",
"expression": {
"type": "AssignmentExpression",
"operator": "=",
"left": {
"type": "Identifier",
"name": "result"
},
"right": node.consequent.expression
}
}
};
if (node.alternate != null && node.alternate.expression.type === 'Literal'){
modifiedNode['alternate'] = {
"type": "ExpressionStatement",
"expression": {
"type":
"AssignmentExpression",
"operator": "=",
"left": {
"type": "Identifier",
"name": "result"
},
"right": node.alternate.expression
}
}
};
}
};
return modifiedNode;
}
});
5)修改好后的ast,生成源代码
var modifiedCode = escodegen.generate(ast);
6)运行
获得结果
$ node exc1.js test1.js
Reading test1.js
=============
if (var1 > 2) result = 3;
else result = 0;
if(var2 < 3) 0
else 1
if (var3 === 9) 1;
=============
if (var1 > 2)
result = 3;
else
result = 0;
if (var2 < 3)
result = 0;
else
result = 1;
if (var3 === 9)
result = 1;
7) 完整代码
exc1.js
-----------
/*
*/
var fs = require('fs'),
esprima = require('esprima'),
estraverse = require('estraverse'),
escodegen = require('escodegen');
function analyzeCode(code) {
var ast = esprima.parse(code);
//console.log(JSON.stringify(ast,null,4));
ast = estraverse.replace(ast, {
leave: function(node, parent)
{
modifiedNode = node;
if (node.type === 'IfStatement') {
if (node.consequent != null && node.consequent.type === 'ExpressionStatement')
{
if (node.consequent.expression.type === 'Literal'){
modifiedNode['consequent'] = {
"type": "ExpressionStatement",
"expression": {
"type": "AssignmentExpression",
"operator": "=",
"left": {
"type": "Identifier",
"name": "result"
},
"right": node.consequent.expression
}
}
};
if (node.alternate != null && node.alternate.expression.type === 'Literal'){
modifiedNode['alternate'] = {
"type": "ExpressionStatement",
"expression": {
"type": "AssignmentExpression",
"operator": "=",
"left": {
"type": "Identifier",
"name": "result"
},
"right": node.alternate.expression
}
}
};
}
};
return modifiedNode;
}
});
var modifiedCode = escodegen.generate(ast);
console.log('=============');
console.log(modifiedCode);
//console.log(JSON.stringify(ast,null,4));
}
if (process.argv.length < 3) {
console.log('Usage: zz.js file.js');
process.exit(1);
}
var filename = process.argv[2];
console.log('Reading ' + filename);
var code = fs.readFileSync(filename);
console.log('=============');
console.log(''+code);
analyzeCode(code);
console.log('Done');
--------------
test1.js
if (var1 > 2) result = 3;
else result = 0;
if(var2 < 3) 0
else 1
if (var3 === 9) 1
8)
各种语言用来修改ast语法树的一些方法收集见:
http://adamrehn.com/articles/ast-instrumentation-examples-by-language#sec___javascript
版权声明:本文为CSDN博主「weixin_33826609」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_33826609/article/details/91671473