Class: Extract::MathCalc
Class Method Summary collapse
Instance Method Summary collapse
- #parse_eval(input) ⇒ Object
- #rpn(input) ⇒ Object
- #shunting_yard(input) ⇒ Object
- #shunting_yard_old(input) ⇒ Object
Class Method Details
.method_missing(sym, *args, &b) ⇒ Object
106 107 108 |
# File 'lib/extract/math_calc.rb', line 106 def method_missing(sym,*args,&b) new.send(sym,*args,&b) end |
Instance Method Details
#parse_eval(input) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# 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) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 |
# 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) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# 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) ⇒ Object
70 71 72 73 74 |
# 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 |