parser generator書いてみた(5)

実行速度測ってみた.
CPUは,2 GHz Intel Core 2 Duo

$ ruby19 -v
ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin9.8.0]
$ time ./sample/calc2.rb
19985

real	0m1.085s
user	0m1.066s
sys	0m0.014s
require_relative '../rdpg.rb'
Lexer = ParserGenerator::Lexer.new(/[ \t\n\r\v]+/) {
  token(:operator, /[+-]/) {|ma| ma[0].to_sym }
  token(:operator2, /[*\/]/) {|ma| ma[0].to_sym }
  token(:integer, /[0-9]+/) {|ma| ma[0].to_i }
  token(:identifier, /[a-z]+/) {|ma| ma[0].to_sym }
}

Parser = ParserGenerator::Parser.new(Lexer) {
  rule(:expr, "term (operator term)*") {|term, ary|
    ary.inject(term) {|r, (op, x)| r.__send__(op.content, x) }
  }
  rule(:term, "factor (operator2 factor)*") {|factor, ary|
    ary.inject(factor) {|r, (op, x)| r.__send__(op.content, x) }
  }
  rule(:factor, "operator? (integer | identifier)") {|sign, token|
    case token.type
    when :integer
      token.content
    when :identifier
      10
    end * if sign && sign.content == :-
            -1
          else
            1
          end
  }
}

parser = Parser.new

p parser.parse("x / 2 + -4 * 5" << " + 1 * 2" * 10000, :expr)

40000tokenで1秒.遅い…のかな.例が恣意的で分かりにくいな.