Antlr3RubyTarget

split-s: ANTLR for Ruby
ここのがそのままでは動かなかったので,適当に改造

calculator.g

grammar Calculator;
options {
  language = Ruby;
}

@init {
  @stack = []
}

@members {

  def result
    @stack[0]
  end
}

parse: expression;

expression: mult (
    '+' mult {
      @stack.push(@stack.pop + @stack.pop)
    }
  | '-' mult {
      a = @stack.pop
      b = @stack.pop
      @stack.push(b - a)
    }
  )* ;

mult: atom (
    '*' atom {
      @stack.push(@stack.pop * @stack.pop)
    }
  | '/' atom {
      a = @stack.pop
      b = @stack.pop
      @stack.push(b / a.to_f)
    }
  )* ;


atom: n=NUMBER { @stack.push($n.text.to_i) }
  | '(' expression ')';

NUMBER: ('0'..'9')+;

WS: (' ' | '\n' | '\t')+ { channel = 99 };

test.rb

require 'CalculatorParser'

lexer = CalculatorLexer.new( STDIN )
parser = CalculatorParser.new( lexer )
parser.parse

puts parser.result

入力例で

(5 + 4) * (10 - 2) / 3

などと書いてあるが,実際にはスペースを入れると文法エラーで例外を飛ばす.