class MathExpression::Parser
Constants
- OPERATORS
Attributes
expression[R]
Public Class Methods
new(expression)
click to toggle source
# File lib/math_expression/parser.rb, line 4 def initialize(expression) @expression = expression end
Public Instance Methods
evaluate()
click to toggle source
# File lib/math_expression/parser.rb, line 73 def evaluate stack = [] to_postfix.each do |token| result = case token when '+' stack.pop + stack.pop when '-' first, second = stack.pop, stack.pop second - first when '*' stack.pop * stack.pop when '/' first, second = stack.pop, stack.pop second / first else token.to_f end stack.push(result) end stack.pop end
to_postfix()
click to toggle source
# File lib/math_expression/parser.rb, line 36 def to_postfix output_queue = [] operator_stack = [] to_tokens.each do |token| type, value = token[:type], token[:value] case type when :number output_queue << value when :operator loop do break if operator_stack.empty? break if left_parenthesis?(operator_stack.last) operator_on_stack_precedence = operator_precedence(operator_stack.last) current_operator_precedence = operator_precedence(value) break if operator_on_stack_precedence <= current_operator_precedence output_queue << operator_stack.pop end operator_stack.push(value) when :parenthesis if left_parenthesis?(value) operator_stack.push(value) else while !left_parenthesis?(operator_stack.last) output_queue << operator_stack.pop end if left_parenthesis?(operator_stack.last) operator_stack.pop end end end end (output_queue + operator_stack.reverse) end
to_tokens()
click to toggle source
# File lib/math_expression/parser.rb, line 8 def to_tokens tokens = [] reading_number = [] form_number = lambda do return if reading_number.empty? num = reading_number.join.to_f tokens << { type: :number, value: num } reading_number = [] end printable_chars = expression.chars.reject { |c| c == ' ' } printable_chars.each do |character| if operator?(character) form_number.call tokens << { type: :operator, value: character } elsif parenthesis?(character) form_number.call tokens << { type: :parenthesis, value: character } else reading_number << character end end form_number.call tokens end
Private Instance Methods
left_parenthesis?(token)
click to toggle source
# File lib/math_expression/parser.rb, line 116 def left_parenthesis?(token) token == '(' end
operator?(token)
click to toggle source
# File lib/math_expression/parser.rb, line 104 def operator?(token) OPERATORS.keys.include?(token) end
operator_precedence(operator)
click to toggle source
# File lib/math_expression/parser.rb, line 108 def operator_precedence(operator) OPERATORS.fetch(operator) end
parenthesis?(token)
click to toggle source
# File lib/math_expression/parser.rb, line 112 def parenthesis?(token) left_parenthesis?(token) || right_parenthesis?(token) end
right_parenthesis?(token)
click to toggle source
# File lib/math_expression/parser.rb, line 120 def right_parenthesis?(token) token == ')' end