File: //usr/share/doc/racc/examples/calc.y
# $Id$
#
# Very simple calculater.
class Calcp
prechigh
nonassoc UMINUS
left '*' '/'
left '+' '-'
preclow
rule
target: exp
| /* none */ { result = 0 }
exp: exp '+' exp { result += val[2] }
| exp '-' exp { result -= val[2] }
| exp '*' exp { result *= val[2] }
| exp '/' exp { result /= val[2] }
| '(' exp ')' { result = val[1] }
| '-' NUMBER =UMINUS { result = -val[1] }
| NUMBER
end
---- header
# $Id$
---- inner
def parse(str)
@q = []
until str.empty?
case str
when /\A\s+/
when /\A\d+/
@q.push [:NUMBER, $&.to_i]
when /\A.|\n/o
s = $&
@q.push [s, s]
end
str = $'
end
@q.push [false, '$end']
do_parse
end
def next_token
@q.shift
end
---- footer
parser = Calcp.new
puts
puts 'type "Q" to quit.'
puts
while true
puts
print '? '
str = gets.chop!
break if /q/i =~ str
begin
puts "= #{parser.parse(str)}"
rescue ParseError
puts $!
end
end