Ruby によるパーサ・コンビネータ rparsec

2007/12/11 10:52am

Java による parsec の実装 JParsec を Ruby に移植した rparsec を勉強中。

パーサ・コンビネータ

Parsec、パーサ・コンビネータについては「最強のパーザー、Parser Combinator - 純粋関数型雑記帳」が参考になる。

Yacc や Bison などのコンパイラ・コンパイラと比較したときのパーサ・コンビネータの強味としては、

などがあるようだ。

rparsec のインストール

普通に RubyForge で gem がホスティングされているので、gem コマンド一発でインストールできる。

% sudo gem install rparsec

四則演算デモ

まずは公式ページにもデモとして紹介されている四則演算から。

#!/usr/local/bin/ruby
require 'rubygems'
require 'rparsec'

class Calculator
  include Parsers
  include Functors
  def parser
    ops = OperatorTable.new.
      infixl(char(?+) >> Plus, 20).
      infixl(char(?-) >> Minus, 20).
      infixl(char(?*) >> Mul, 40).
      infixl(char(?/) >> Div, 40).
      prefix(char(?-) >> Neg, 60)
    expr = nil
    term = integer.map(&To_i) | char('(') >> lazy{expr} << char (')')
    delim = whitespace.many_
    expr = delim >> Expressions.build(term, ops, delim)
  end
end

これを calc.rb として保存し、irb から簡単な数式を処理させてみる。

% irb
irb(main):001:0> require 'calc'
=> true
irb(main):002:0> Calculator.new.parser.parse '1+2*(3-1)'
=> 5
# => 5