]追加された行はこの色です。削除された行はこの色です。スクリプト解析は文字列を解析する関数とファイルを解析する関数がありますが、それらの違いは所詮、入力の違いなのでmrb_parse_string()をスクリプト解析のエントリポイントとして読み進めていきたいと思います。mrb_parse_string()は渡された文字列をstrlenしてmrb_parse_nstring()に渡しているだけなのでmrb_parse_nstring()を見てみましょう。スクリプト解析で鍵となるのはmrb_parser_state構造体のようです。mrb_parser_stateはinclude/compile.hに書かれています。上記ではparser_stateになっていますが、parser_stateはmrb_parser_stateをtypedefしたものです。次にmrb_parser_parse()を見てみます。長めですが全部貼り付け。いうことがわかります。node(mrb_ast_nodeがtypedefされたもの)は上記のmrb_parser_parse()を見てもわかるとおり、LISPのリスト構造と同じになっています。CRubyのNODE構造体に比べると驚くほどシンプルです。シンプルな分は運用で回避。parse.yの前半部分にはリスト操作、およびそれを使って解析ツリーを作るための関数群が定義されています。具体的にスクリプトをNODEに変換してみましょう。対象とするスクリプトは[[Ruby1.9のスクリプト解析>Ruby1.9/スクリプト解析を読む]]で変換してみたものと同じスクリプトを使います((余談ですが、2012/5/29時点でKernel#randが実装されていないため、スクリプトを実行するとNoMethodErrorになります:-P))。bin/mrubyは--verboseオプションを付けるとNODEツリーがダンプされます((実行コードもダンプされますがそれは次で取り上げます))。上記のスクリプトを食わせると以下のNODEツリーが出力されました。それではどういうルールを通ることでこのようなNODEツリーが構築されるのかを追っていくことにします。クラス定義があります。keyword_class、とルールが進んでいきます。忘れてましたがそういえばRubyではクラス定義も式でしたね。keyword_defと進みます。続いて、引数記述の解析に移ります。Rubyは、通常引数、オプション引数、残余引数、ブロック引数と引数の種類がたくさんあるので引数解析のルールも様々なパターンが書かれています。f_norm_arg、とルールが進んでいきます。代入は飛ばしてブロック付きメソッド実行に移ります。brace_block」です。brace_blockとなっていますが、do〜endを使った場合もマッチします。opt_paren_args」にマッチします。brace_block」の際に呼ばれるcall_with_block()を見てみましょう。慣れないとわかりづらいですが、carはリストの先頭要素、cdrはリストの先頭を除いたリストです。cdrのcdrのcdrは元のリストの前3要素を除いたリストになります。d)とすると結果は以下のようになります。call_with_block()中のnは引数情報を指すことがわかります。[[Ruby1.9のスクリプト解析>Ruby1.9/スクリプト解析を読む]]のNODEと比較するとCRubyとmrubyで構築されるノードと微妙に違うことがわかります。CRubyと比べてNODE_SCOPEがルートにしかありませんが、あくまでNODE表現上の話であってスコープがCRubyと違うということではないようです。いうわけでmrubyのスクリプト解析を見てきました。いったところでしょうか。