Racc

P

Peter Suk

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. <http://i.loveruby.net/en/man/racc/parser.html> 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 --------
 
S

Steven Jenkins

Peter said:
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

That means there's no rule that matches the input.
I am feeding it tokens that are two-element arrays, as stated in the
documentation. <http://i.loveruby.net/en/man/racc/parser.html> But it
is not at all clear what should be in the second element.

Racc doesn't care. As long as the lexer and your productions agree on
the type (or on the duck-typing), it's OK.

Your understanding appears to be fine. You just have a simple bug--see
below.
[snip]
-------- 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

@index += 1
return rval
end

end
-------- end --------

It's returning two NUMBERS in a row, which is a syntax error in your
grammar.

Don't you love bugs like this? If you didn't suspect your understanding
of Racc, you'd probably have found in in two minutes. HTH.

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top