class RpnCalculator::RPNParser

Public Class Methods

new(string) click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 3
def initialize(string)
  raise ArgumentError, 'only numbers and operators allowed as arguments' unless /^[0-9\+\-\*\/\s\.\(\)]+$/ === string
  @string = adjust_string(string)
end
parse(str) click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 13
def self.parse(str) self.new(str).parse end

Public Instance Methods

adjust_string(str) click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 7
def adjust_string(str)
  str.gsub!(/(?<=[0-9])(?=[\+\-\*\/])/,' ')
  str.gsub!(/(?<=[\+\-\*\/])(?=[0-9])/,' ')
  str.gsub(/\s+/,' ')
end
exponent() click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 38
def exponent
  @current = parenthesis
  return @current if self.return_check
  left  = @current.split('**')
  return left.pop if left.count == 1
  right = left.pop
  left  = left.join('**').split(' ')
  exp   = "#{left.pop} ** #{right}"
  return exp if left.count == 0
  RPNParser.parse("#{left.join(' ')} #{RPNParser.parse(exp)}")
end
mult_div() click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 27
def mult_div
  @current = exponent
  return @current if self.return_check
  left = @current.split(/(?<=[0-9\s])(?=[\*\/])/)
  return left.pop if left.count == 1
  right = left.pop.split(' ')
  left = left.join.split(' ')
  evaluated = "#{left.pop} #{right.shift} #{right.shift}"
  return evaluated if left.count + right.count == 0
  RPNParser.parse("#{left.join(' ')}#{RPNParser.parse(evaluated)}#{right.join(' ')}")
end
parenthesis() click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 49
def parenthesis
  left   = @string.split('(')
  return left.pop if left.count == 1
  right  = left.pop.split(')')
  middle = right.shift
  parens = [left.join('('),middle,right.join(')')]
  RPNParser.parse("#{parens[0]} #{RPNParser.parse(parens[1])} #{parens[2]}")
end
parse() click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 15
def parse
  @current = mult_div
  return @current if self.return_check
  evaluated = @current.split(' ')
  numbers   = [evaluated.shift]
  operators = []
  while evaluated.count > 0
    operators << evaluated.shift
    numbers   << evaluated.shift
  end
  RPN.evaluate([numbers,operators])
end
return_check() click to toggle source
# File lib/rpn_calculator/rpn_parser.rb, line 14
  def return_check()  @current == Float(@current) rescue(false) end
  def parse
    @current = mult_div
    return @current if self.return_check
    evaluated = @current.split(' ')
    numbers   = [evaluated.shift]
    operators = []
    while evaluated.count > 0
      operators << evaluated.shift
      numbers   << evaluated.shift
    end
    RPN.evaluate([numbers,operators])
  end
  def mult_div
    @current = exponent
    return @current if self.return_check
    left = @current.split(/(?<=[0-9\s])(?=[\*\/])/)
    return left.pop if left.count == 1
    right = left.pop.split(' ')
    left = left.join.split(' ')
    evaluated = "#{left.pop} #{right.shift} #{right.shift}"
    return evaluated if left.count + right.count == 0
    RPNParser.parse("#{left.join(' ')}#{RPNParser.parse(evaluated)}#{right.join(' ')}")
  end
  def exponent
    @current = parenthesis
    return @current if self.return_check
    left  = @current.split('**')
    return left.pop if left.count == 1
    right = left.pop
    left  = left.join('**').split(' ')
    exp   = "#{left.pop} ** #{right}"
    return exp if left.count == 0
    RPNParser.parse("#{left.join(' ')} #{RPNParser.parse(exp)}")
  end
  def parenthesis
    left   = @string.split('(')
    return left.pop if left.count == 1
    right  = left.pop.split(')')
    middle = right.shift
    parens = [left.join('('),middle,right.join(')')]
    RPNParser.parse("#{parens[0]} #{RPNParser.parse(parens[1])} #{parens[2]}")
  end
end