オレオレ言語の構文木をYahoo! UIでツリー表示する方法
オレオレ言語を作る場合、メモリ上に構文木が正しくできているかどうかが気になりますよね。Firebugのようにデータ構造を折りたたみ可能なツリー表示ができないかなあと思って、Yahoo! UIを使う方法を考えてみました。
サンプルとして自作のBrainf*ckインタプリタに組み込んでみました。以下のように出力されます。まあBrainf*ckごときに構文木を使うもどうかと思いますが。
ソース(hello.bf)
++++++++++[>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++.<<+++++++++++++++. >.+++.------.--------.>+.>.
うーん、素のBrainf*ckだとあんまりありがたみが分からないかも。
インタプリタの最適化オプションを立てたらこんな感じ。
実現方法
まず下のようなJavaScript関数入りHTMLを出力するDataDumpクラスを用意します。
<link rel="stylesheet" type="text/css" href="./build/treeview/assets/skins/sam/treeview.css" /> <script type="text/javascript" src="./build/yahoo/yahoo-min.js" ></script> <script type="text/javascript" src="./build/event/event-min.js" ></script> <script type="text/javascript" src="./build/treeview/treeview-min.js" ></script> <script type="text/javascript"> var treeTail; var treeParent; var treeStack = []; function drawTree() { var tree = new YAHOO.widget.TreeView("Tree"); var root = tree.getRoot(); treeParent = root; treeDef(); tree.draw(); } function treeAdd(s) { var n = new YAHOO.widget.TextNode(s, treeParent, false); treeTail = n; } function treeDown() { treeStack.push(treeParent); treeParent = treeTail; } function treeUp() { treeTail = treeParent; treeParent = treeStack.pop(); }
各ノードクラスにはdump()メソッドを用意して、上記関数を呼ぶJavaScriptコードを出力するようにします。
void Variable::dump(FILE* fd) { fprintf(fd, "treeAdd('Variable: %s');\n", name); fprintf(fd, "treeDown();\n"); fprintf(fd, "treeAdd('Value: %d');\n", val); fprintf(fd, "treeUp();\n"); if (next) next->dump(fd); }
構文木ができたタイミングで上記のHTMLを生成します。
DataDump dd; if (dd.init("brainfk.html", srcfile) == 0) { dd.writeHeader(); node.tree->dump(dd.getFd()); dd.writeFooter(); }
ブラウザで表示するときは、Yahoo! UIのbuildフォルダを同じ場所にコピーしておきます。
ね、簡単でしょ?