raccについて
使い方
racc calc-ja.y
racc -e ruby -o calc calc-ja.y
こんな感じで生成物は通常 a.y -> a.tab.rbになるのでそのままrequireすればクラスライブラリ
ソースの形
aaa.y class Calcp prechigh nonassoc UMINUS left '*' '/' left '+' '-' preclow rule target: exp | /* none */ { result = 0 } ; exp: exp '+' exp { result += val[2] } | '(' exp ')' { result = val[1] } | '-' NUMBER = UMINUS { result = -val[1] } | NUMBER ; end ---- header ---- # calc.rb : generated by racc ---- inner ---- def parse( str ) @q = [] do_parse end def next_token @q.shift end ---- footer ----
=最初のクラスがパーサにコンパイルされる
==rule...endの間がBNFで記述されるところ
===resultが parseの返値となる
===val[n]はBNFの右辺の値
====例えば exp '+' exp は val[0] val[1] val[2]となる
===BNFの記法
==== ''|''=or '':''='=' '';''=終了
=innerは最初のクラスにそのまま取り込まれる
==parseメソッドはスキャナとして定義される(別に名前は何でも良さそうだ)
===do_parseでパース開始
==next_takenはパーサから呼び出される。
詳しくは http://www1.u-netsurf.ne.jp/~brew/mine/ja/racc/grammer.html