2011-03-29
■ [ruby] Ruby用のPEGパーサParslet
via @frsyuki
Ruby用のPEGパーサには既にTreetopがあるけど、エラー表示が改善されてたりするようだ。
Treetopは独自の文法だったけど、ParsletはRubyの内部DSLになっている。 また、Treetopは文法と同じところにアクションも書くけれど、Parsletは「Parser」と「Transformer」を別々に定義して組み合わせるというAPIになっている。
チュートリアルを見れば雰囲気はだいたい分かると思う。
とりあえず電卓(足し算だけだけど)。
Parserは構文木をHashとして返す。"1"@0みたいなのはParslet::Sliceのインスタンスで、0行目にある"1"という文字列を表している。.as(:foo)みたいに名前を付けたノードだけが構文木に含まれるようだ。
TransformerはHashに対しパターンマッチを行う。「simple」というのはHashでもArrayでもないもののことらしい。公式のチュートリアルでは各ノードごとにStructを定義していたけど、 簡単なものならTransformerに直接アクションを書けばいいと思う。
ところで、Struct.newの返り値を親クラスにするという発想はなかった。
class IntLit < Struct.new(:int) def eval; int.to_i; end end
これよりはまだ気持ち悪くないと思う。
IntLit = Struct.new(:int) do def eval; int.to_i; end end