class Extract::MathCalc
Public Class Methods
method_missing(sym,*args,&b)
click to toggle source
# File lib/extract/math_calc.rb, line 106 def method_missing(sym,*args,&b) new.send(sym,*args,&b) end
Public Instance Methods
parse_eval(input)
click to toggle source
# File lib/extract/math_calc.rb, line 89 def parse_eval(input) raw_input = input #raise input.map { |x| x.text_value }.inspect input = input.map { |x| MathWrapper.new(:str => (x.respond_to?(:excel_value) ? x.excel_value : x.text_value)) } #input = input.split(" ") if input.kind_of?(String) res = shunting_yard(input) #puts "before rpn #{res.inspect}" begin res = rpn(res) rescue => exp puts raw_input.map { |x| x.text_value }.inspect puts res.inspect raise exp end end
rpn(input)
click to toggle source
# File lib/extract/math_calc.rb, line 76 def rpn(input) results = [] input.each do |object| if object.operator? r, l = results.pop, results.pop results << object.apply(l, r) else results << object end end results.first end
shunting_yard(input)
click to toggle source
# File lib/extract/math_calc.rb, line 45 def shunting_yard(input) [].tap do |rpn| # where I store operators before putting them onto final rpn list operator_stack = [] input.each do |object| if object.operator? op1 = object # while we have an operator on the temp stack # and that op on the temp stack has a higher precedence than the current op while (op2 = operator_stack.last) && (op1.left_associative? ? op1.precedence <= op2.precedence : op1.precedence < op2.precedence) rpn << operator_stack.pop end operator_stack << op1 else rpn << object end end rpn << operator_stack.pop until operator_stack.empty? end end
shunting_yard_old(input)
click to toggle source
# File lib/extract/math_calc.rb, line 70 def shunting_yard_old(input) input = input.map { |x| MathWrapper.new(:str => x) } res = shunting_yard_inner(input) res.map { |x| x.str } end