Parsing/RPN/Ruby: Difference between revisions

Content added Content deleted
m (link to pages that link here)
m (add another couple of tests)
Line 73: Line 73:
rpn_expr << op_stack.pop
rpn_expr << op_stack.pop
end
end
self.new(rpn_expr.join(" "))
obj = self.new(rpn_expr.join(" "))
debug "RPN = #{obj.to_s}"
obj
end
end


Line 101: Line 103:
end
end
@value = stack.pop
@value = stack.pop
debug "Value = #@value"
@value
end
end


Line 135: Line 139:
# express the AST as a string
# express the AST as a string
def to_infix
def to_infix
to_infix_tree.to_s
expr = to_infix_tree.to_s
debug "Infix = #{expr}"
expr
end
end


# express the AST as a string, but in a form that allows Ruby to evaluate it
# express the AST as a string, but in a form that allows Ruby to evaluate it
def to_ruby
def to_ruby
to_infix_tree.to_ruby
expr = to_infix_tree.to_ruby
debug "Ruby = #{expr}"
expr
end
end


Line 210: Line 218:
rpn = RPNExpression.new @rpn_expr
rpn = RPNExpression.new @rpn_expr
value = rpn.eval
value = rpn.eval
debug "value = #{value}"
assert_equal @value, value
assert_equal @value, value
end
end
Line 217: Line 224:
rpn = RPNExpression.new @rpn_expr
rpn = RPNExpression.new @rpn_expr
infix = rpn.to_infix
infix = rpn.to_infix
debug "infix = #{infix}"
debug "ruby = #{rpn.to_ruby}"
assert_equal @infix_expr, infix
assert_equal @infix_expr, infix
assert_equal @value, eval(rpn.to_ruby)
assert_equal @value, eval(rpn.to_ruby)
Line 225: Line 230:
def test_infix_to_rpn
def test_infix_to_rpn
rpn = RPNExpression.from_infix @infix_expr
rpn = RPNExpression.from_infix @infix_expr
rpn_expr = rpn.to_s
assert_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[idx], obj.to_s
end
$DEBUG = old_debug
end
end
end</lang>
end</lang>
Line 252: Line 274:
/ DIV [3, 0.0001220703125]
/ DIV [3, 0.0001220703125]
+ ADD [3.0001220703125]
+ ADD [3.0001220703125]
value = 3.0001220703125
Value = 3.0001220703125
.
.
for Infix expression: 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
for Infix expression: 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
Line 273: Line 295:
^ PUSH OP ["3", "4", "2", "*", "1", "5", "-", "2"] ["+", "/", "^", "^"]
^ PUSH OP ["3", "4", "2", "*", "1", "5", "-", "2"] ["+", "/", "^", "^"]
3 PUSH V ["3", "4", "2", "*", "1", "5", "-", "2", "3"] ["+", "/", "^", "^"]
3 PUSH V ["3", "4", "2", "*", "1", "5", "-", "2", "3"] ["+", "/", "^", "^"]
rpn = 3 4 2 * 1 5 - 2 3 ^ ^ / +
RPN = 3 4 2 * 1 5 - 2 3 ^ ^ / +
.
..
for RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
for RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Term Action Stack
Term Action Stack
Line 290: Line 312:
/ 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]>>>]
/ 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]>>>>]
+ 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]>>>>]
infix = 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
Infix = 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
ruby = 3 + 4 * 2.to_f / ( 1 - 5 ) ** 2 ** 3
Ruby = 3 + 4 * 2.to_f / ( 1 - 5 ) ** 2 ** 3
.
.


Finished tests in 0.007031s, 426.7101 tests/s, 568.9468 assertions/s.
Finished tests in 0.012002s, 333.2831 tests/s, 999.8494 assertions/s.


3 tests, 4 assertions, 0 failures, 0 errors, 0 skips</pre>
4 tests, 12 assertions, 0 failures, 0 errors, 0 skips</pre>