parser generator書いてみた
現状こんな感じで書ける.
lexer = Lexer.new("x + 4 * 5", /[ \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 = Parser.new(:expr, lexer) { rule(:expr, seq(:term, repeat(:operator, :term))) {|(term, ary)| ary.inject(term) {|r, (op, x)| r.__send__(op.content, x) } } rule(:term, seq(:factor, repeat(:operator2, :factor))) {|(factor, ary)| ary.inject(factor) {|r, (op, x)| r.__send__(op.content, x) } } rule(:factor, select(:integer, :identifier)) {|token| case token.type when :integer token.content when :identifier 10 end } } p parser.parse # => 30
COOL!!
解析木はこんな感じ.
[[#<Token x>, []], [[#<Token +>, [#<Token 4>, [[#<Token *>, #<Token 5>]]]]]]
(2009-10-12 17:30 追記)ちょっとした修正