There's an echo in my head

日々のメモ。

インタラクティブにRipperで構文解析するIRipperというREPLを作った

github.com

「この記述はRubyにどういうふうに解析されているんだろう!?」という疑問を逐次解決していくためのREPLとして作りました。

lexsexptokenizeというRipperのメソッドを使って、引数で与えられたコードを解析して表示します。

$ iripper
iripper> tokenize 1 + 1
["1", " ", "+", " ", "1"]
iripper> sexp 1 + 1
[:program, [[:binary, [:@int, "1", [1, 0]], :+, [:@int, "1", [1, 4]]]]]
iripper> lex 1 + 1
[[[1, 0], :on_int, "1", EXPR_END|EXPR_ENDARG],
 [[1, 1], :on_sp, " ", EXPR_END|EXPR_ENDARG],
 [[1, 2], :on_op, "+", EXPR_BEG],
 [[1, 3], :on_sp, " ", EXPR_BEG],
 [[1, 4], :on_int, "1", EXPR_END|EXPR_ENDARG]]

「いちいちlexと入力するのが面倒くさい」「ワシはtokenizeにしか興味が無いんじゃ」「S式だけを見ていたい」というように、実行したいメソッド(READMEでは「コマンド」と記載していますが)が決まりきっている場合には、起動引数もしくはdefaultコマンドでデフォルトのメソッドを指定するのが便利でしょう。

$ iripper tokenize
iripper(tokenize)> 1 + 1
["1", " ", "+", " ", "1"]
iripper(tokenize)> default sexp
iripper(sexp)> 1 + 1
[:program, [[:binary, [:@int, "1", [1, 0]], :+, [:@int, "1", [1, 4]]]]]
iripper(sexp)> default
iripper> tokenize 1 + 1
["1", " ", "+", " ", "1"]

例の最後のように、defaultコマンドに何も与えなければデフォルトのメソッド指定を外します。

履歴やカーソル移動などはできません。気が向いたらReadlineなどで対応します。

このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。