Skip to content

Instantly share code, notes, and snippets.

@takehiko
Created March 11, 2015 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takehiko/0a37a79967c000c4efa1 to your computer and use it in GitHub Desktop.
Save takehiko/0a37a79967c000c4efa1 to your computer and use it in GitHub Desktop.
6÷2(1+2)=1 using Racc
#!/usr/bin/env ruby
# $ ruby calc1.rb
# 1+2×3=7
# 3×(8+5×(6-2))÷2=42
# 6÷2(1+2)=1
# 6÷2×(1+2)=9
# Racc required (gem install racc)
system("rm calc.y") if test(?f, "calc.y")
system("rm calc.rb") if test(?f, "calc.rb")
open("calc.y", "w") do |f_out|
f_out.print DATA.read
end
command = "racc -o calc.rb calc.y"
result = `#{command} 2>&1`
if $DEBUG
puts "$ " + command
print result
end
require "./calc.rb"
calc = Calc.new()
["1+2×3", "3×(8+5×(6-2))÷2",
"6÷2(1+2)", "6÷2×(1+2)"].each do |expr|
puts expr + "=" + calc.parse(expr).to_s
end
# http://mollifier.hatenablog.com/entry/20090823/p1
__END__
class Calc
token NUM
prechigh
left CONCAT
left '×' '÷'
left '+' '-'
preclow
rule
expr : expr '+' expr { result = val[0] + val[2] }
| expr '-' expr { result = val[0] - val[2] }
| expr '×' expr { result = val[0] * val[2] }
| expr expr =CONCAT { result = val[0] * val[1] }
| expr '÷' expr { result = val[0] / val[2] }
| prim { result = val[0] }
prim : NUM { result = val[0] }
| '(' expr ')' { result = val[1] }
end
---- inner
def parse(str)
@tokens = str.split(/([\(\)+-×÷])/).select{|c| !c.nil? && c != ""}
do_parse()
end
def next_token()
token = @tokens.shift()
case token
when /^\d+\z/
return [:NUM, token.to_i]
when nil
return nil
else
return [token, nil]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment