From: Peter Suk Date: 2005-04-25T06:06:10+09:00 Subject: Racc Folks, I need help using Racc. I've been trying to go through the basic calculator example, but no go. The grammar is processed without any shift-reduce conflicts. It appears I am feeding the wrong kind of tokens to it. I keep getting: Parsing file: /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb:377:in `on_error': (Racc::ParseError) parse error on value 1 (NUMBER) from /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb:104:in `_racc_do_parse_c' from /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb:104:in `__send__' from /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb:104:in `do_parse' from racc-calc-2.y:47:in `parse' from ruby_calc_test.rb:20 I am feeding it tokens that are two-element arrays, as stated in the documentation. But it is not at all clear what should be in the second element. tokens = [ [ :NUMBER, 1 ], [ :PLUS, "+" ], [ :NUMBER, 2 ], [ false, false ] ] --Peter -- There's neither heaven nor hell, save what we grant ourselves. There's neither fairness nor justice, save what we grant each other. -------- ruby_calc_test.rb -------- #!/usr/bin/ruby require "FakeLexer" require "RubyCalcParser" ## reuse the same parser object p = RubyCalcParser.new #p.yydebug = true #p.yyerror = $stdout print "Parsing file:\n" tokens = [ [ :NUMBER, 1 ], [ :PLUS, "+" ], [ :NUMBER, 2 ], [ false, false ] ] p.lexer = FakeLexer.new(tokens) print(p.parse.inspect) print "\n" -------- racc-calc-2.y -------- class RubyCalcParser prechigh left TIMES DIVIDE left PLUS MINUS preclow token NUMBER PLUS MINUS TIMES DIVIDE LPAREN RPAREN rule exp: NUMBER { TestNumNode.new($1, "+") } | exp PLUS exp { TestBinaryOpNode.new($1, "+", $3) } | exp MINUS exp { TestBinaryOpNode.new($1, "-", $3) } | exp TIMES exp { TestBinaryOpNode.new($1, "*", $3) } | exp DIVIDE exp { TestBinaryOpNode.new($1, "/", $3) } | LPAREN exp RPAREN { TestExpNode.new($2) } | LPAREN error RPAREN { 1 } ## example error recovery--a bad expression is interpreted as a 1 ; end # RubyCalcParser ---- header ---- require 'RubyCalcAst' ---- inner ---- def initialize @ast = nil end attr_accessor :lexer ; def parse() return do_parse() end protected def next_token return @lexer.yylex() end -------- RubyCalcAst.rb -------- class TestNumNode def initialize(num, sign) @num = num @sign = sign end end class TestBinaryOpNode def initialize(term1, op, term2) @term1 = term1 @op = op @term2 = term2 end end class TestExpNode def initialize(exp) @exp = exp end end -------- FakeLexer.rb -------- require 'RubyCalcParser' class FakeLexer def initialize(tokens) @tokens = tokens @index = 0 end def reset() @index = 0 end def yylex() rval = @tokens[@index] @index += @index return rval end end -------- end --------