JRuby で AST を作る
JRuby で AST 作ってみた。
だって AST が好きだから。
JRuby のバージョンは 1.3.1。
hello.jruby.RubyASTViewer
package hello.jruby; import java.io.ByteArrayInputStream; import org.jruby.Ruby; import org.jruby.ast.Node; /** * Ruby AST Viewer * @author mallowlabs */ public class RubyASTViewer { private String src = ""; private Node ast = null; /** * Constructor. * @param src ruby source code */ public RubyASTViewer(String src) { super(); this.src = src; } /** * Show AST. */ public void view() { parse(); traverse(ast, 0); } /** * Traverse AST. * @param node * @param indent */ protected void traverse(Node node, int indent) { for (int i = 0; i < indent; i++) System.out.print(" "); System.out.println(node.getClass().toString() + " " + node.getPosition().toString()); for (Node child : node.childNodes()) { traverse(child, indent + 2); } } /** * Parse ruby source code. */ protected void parse() { ast = Ruby.newInstance().parseInline( new ByteArrayInputStream(src.getBytes()), "-", null); } /** * Entry point. * @param args */ public static void main(String[] args) { final String src = "puts \"Hello world \"\nputs 1+1"; new RubyASTViewer(src).view(); } }
実行結果
class org.jruby.ast.RootNode -:0 class org.jruby.ast.BlockNode -:0 class org.jruby.ast.NewlineNode -:0 class org.jruby.ast.FCallOneArgNode -:0 class org.jruby.ast.ArrayNode -:0 class org.jruby.ast.StrNode -:0 class org.jruby.ast.NewlineNode -:1 class org.jruby.ast.FCallOneArgNode -:1 class org.jruby.ast.ArrayNode -:1 class org.jruby.ast.CallOneArgNode -:1 class org.jruby.ast.FixnumNode -:1 class org.jruby.ast.ArrayNode -:1 class org.jruby.ast.FixnumNode -:1
感想
- 簡単
- AST のノードはそれぞれコード上の行番号を保持してて Java っぽい
- NewLineNode というのがなんだか新鮮
- AST 萌え