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:
arseError)
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 ],
[
LUS, "+" ],
[ :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 ],
[
LUS, "+" ],
[ :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 --------
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:
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 ],
[
[ :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 ],
[
[ :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 --------