Parsing/RPN/Ruby: Difference between revisions

m
Avoid miscounting task entries twice
(collect Ruby code for parsing RPN tasks)
 
m (Avoid miscounting task entries twice)
 
(3 intermediate revisions by one other user not shown)
Line 1:
<span style='font-family: "Linux Libertine",Georgia,Times,serif;font-size:150%;'>[[Ruby]]</span><hr>
Code for parsing and evaluating RPN expressions. See
* [[Parsing/RPN calculator algorithm]]
* [[Parsing/RPN to infix conversion]]
* [[Parsing/Shunting-yard algorithm]]
 
<lang ruby>class RPNExpression
 
Line 68 ⟶ 74:
rpn_expr << op_stack.pop
end
obj = self.new(rpn_expr.join(" "))
debug "rpnRPN = #{rpn_exprobj.to_s}"
obj
end
 
Line 96 ⟶ 104:
end
@value = stack.pop
debug "valueValue = #{@value}"
@value
end
 
Line 130 ⟶ 140:
# express the AST as a string
def to_infix
expr = to_infix_tree.to_s
debug "infixInfix = #{infixexpr}"
expr
end
 
# express the AST as a string, but in a form that allows Ruby to evaluate it
def to_ruby
expr = to_infix_tree.to_ruby
debug "rubyRuby = #{rpn.to_rubyexpr}"
expr
end
 
Line 205 ⟶ 219:
rpn = RPNExpression.new @rpn_expr
value = rpn.eval
debug "value = #{value}"
assert_equal @value, value
end
Line 212 ⟶ 225:
rpn = RPNExpression.new @rpn_expr
infix = rpn.to_infix
debug "infix = #{infix}"
debug "ruby = #{rpn.to_ruby}"
assert_equal @infix_expr, infix
assert_equal @value, eval(rpn.to_ruby)
Line 220 ⟶ 231:
def test_infix_to_rpn
rpn = RPNExpression.from_infix @infix_expr
rpn_exprassert_equal =@rpn_expr, rpn.to_s
end
debug "rpn = #{rpn_expr}"
 
assert_equal @rpn_expr, rpn_expr
def test_other_expressions
old_debug = $DEBUG
$DEBUG = false
 
rpn = ["56 34 213.7 + * 678 -", "1 56 35 + 16 9 - / +"]
infix = ["56 * ( 34 + 213.7 ) - 678", "1 + ( 56 + 35 ) / ( 16 - 9 )"]
value = ["13193.2", "14.0"]
 
[0, 1].each do |idx|
obj = RPNExpression.new rpn[idx]
assert_equal value[idx], "%.1f" % obj.eval
assert_equal infix[idx], obj.to_infix
assert_equal value[idx], "%.1f" % eval(obj.to_ruby)
obj = RPNExpression.from_infix infix[idx]
assert_equal @rpn_exprrpn[idx], rpn_exprobj.to_s
end
$DEBUG = old_debug
end
end</lang>
Line 247 ⟶ 275:
/ DIV [3, 0.0001220703125]
+ ADD [3.0001220703125]
valueValue = 3.0001220703125
.
for Infix expression: 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
Line 268 ⟶ 296:
^ PUSH OP ["3", "4", "2", "*", "1", "5", "-", "2"] ["+", "/", "^", "^"]
3 PUSH V ["3", "4", "2", "*", "1", "5", "-", "2", "3"] ["+", "/", "^", "^"]
rpnRPN = 3 4 2 * 1 5 - 2 3 ^ ^ / +
..
for RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Term Action Stack
Line 285 ⟶ 313:
/ DIV [node[3], node[/]<left=node[*]<left=node[4], right=node[2]>, right=node[^]<left=node[-]<left=node[1], right=node[5]>, right=node[^]<left=node[2], right=node[3]>>>]
+ ADD [node[+]<left=node[3], right=node[/]<left=node[*]<left=node[4], right=node[2]>, right=node[^]<left=node[-]<left=node[1], right=node[5]>, right=node[^]<left=node[2], right=node[3]>>>>]
infixInfix = 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
rubyRuby = 3 + 4 * 2.to_f / ( 1 - 5 ) ** 2 ** 3
.
 
Finished tests in 0.007031s012002s, 426333.71012831 tests/s, 568999.94688494 assertions/s.
 
34 tests, 412 assertions, 0 failures, 0 errors, 0 skips</pre>
10,327

edits