-
Pythonの抽象構文木をGraphvizで可視化する (
@kaityo256 さん ) - Ruby2.6 + Graphvizで抽象構文木をグラフにしてみる ( 私 )
- Go + Graphviz で抽象構文木をグラフにしてみる ( 私 )
のシリーズを、JavaScript(node.js) で。
JS の AST を得る方法はたくさんあるみたいなんだけど、 esprima というライブラリを選択した。
まずはソースコード。
node.js
var esprima = require('esprima');
var fs = require('fs');
function walk(parent, edge, node, proc) {
if (node === null || "object" != typeof node) {
return;
}
proc(parent, edge, node);
for (var key in node) {
walk(node, key, node[key], proc);
}
}
function quoted(node) {
var s = "";
if ("type" in node) {
s += node.type;
}
if ("name" in node) {
s += "(" + node.name + ")";
}
if ("value" in node) {
s += "[" + node.value + "]";
}
if ("operator" in node) {
s += "(" + node.operator + ")";
}
if (Array.isArray(node)){
s = "Array";
}
var j = JSON.stringify([s]);
return j.substr(1, j.length - 2);
}
function codeToDot(src) {
var ast = esprima.parse(src);
var str = "";
var id = 0;
walk(null, null, ast, function (parent, edge, node) {
node["dot_id"] = "n" + (id++);
if ( parent!==null ){
str += parent.dot_id + "->" + node.dot_id + "[taillabel=\"" + edge + "\"]\n";
}
var label = quoted(node);
str += node.dot_id + "[ label=" + label + "]\n";
});
return str;
}
fs.readFile(process.argv[2], 'utf8', function (err, text) {
dot = codeToDot(text);
process.stdout.write("digraph{graph [dpi=288;]; node[ shape=box ];\n");
process.stdout.write(dot);
process.stdout.write("}\n");
});
関数 quoted
が不十分かもしれない。
食べさせたコードはこんな感じ:
javascript
function hoge(foo, bar) {
for (var ix in bar) {
var val = bar[ix];
if (val < ix) {
console.log(val + (-10 + 100));
}
}
}
hoge("45", ["34", "56"]);
for
と if
と関数定義、関数呼び出し、配列リテラル、あたりを入れてみた。
出来上がる絵はこんな感じ:
やはり面白い。