Parsing/RPN/Ruby: Difference between revisions
m
Avoid miscounting task entries twice
(collect Ruby code for parsing RPN tasks) |
Thundergnat (talk | contribs) 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(" "))
obj
end
Line 96 ⟶ 104:
end
@value = stack.pop
@value
end
Line 130 ⟶ 140:
# express the AST as a string
def to_infix
expr = to_infix_tree.to_s
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
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
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]
end
$DEBUG = old_debug
end
end</lang>
Line 247 ⟶ 275:
/ DIV [3, 0.0001220703125]
+ ADD [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"] ["+", "/", "^", "^"]
..
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]>>>>]
.
Finished tests in 0.
|