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