> Some people like to work with a postfix notation (often called Reverse Polish > Notation or just RPN) though, which doesn't require parentheses for the same > equation: Since I recently wrote a small RPN calculator in ruby (http://www.vim.org/scripts/script.php?script_id=2040), I found this idea interesting. Here is my take on this. It provides some kind of simplicistic pattern matcher and should be extensible. The assumption is made that the input consists of numeric data and predefined operators. No error checking is done. Regards, Thomas. class Quiz148 class << self def run(args) iqueue = args.map {|e| e.split(/\s+/)}.flatten return Quiz148.new(iqueue).process end end def initialize(iqueue) @iqueue = iqueue @depth = 0 @stack = [] @ops = { '+' => [10], '-' => [10, [String, String, false, true]], '*' => [5], '/' => [5], '^' => [5, [String, Numeric, true, false]], } @opnames = @ops.keys end def get_elt(op, idx=-1, other_value=nil) val = @stack.delete_at(idx) case val when Array eop, val = val else eop = nil end if op and eop opp, *opatterns = @ops[op] eopp, *epatterns = @ops[eop] if eopp > opp return '(%s)' % val end end return val end def process @iqueue.each do |token| if @opnames.include?(token) val1 = get_elt(token, -2) val2 = get_elt(token, -1) @ops[token][1..-1].each do |p1, p2, e1, e2| if val1.kind_of?(p1) and val2.kind_of?(p2) val1 = '(%s)' % val1 if e1 val2 = '(%s)' % val2 if e2 break end end @stack << [token, '%s %s %s' % [val1, token, val2]] else @stack << eval(token) end end # The stack should include only one element here. A check would # be necessary. get_elt(nil) end end if __FILE__ == $0 if ARGV.empty? puts Quiz148.run('2 3 +') == '2 + 3' puts Quiz148.run('56 34 213.7 + * 678 -') == '56 * (34 + 213.7) - 678' puts Quiz148.run('1 56 35 + 16 9 - / +') == '1 + (56 + 35) / (16 - 9)' puts Quiz148.run('1 2 + 3 4 + +') == '1 + 2 + 3 + 4' puts Quiz148.run('1 2 - 3 4 - -') == '1 - 2 - (3 - 4)' puts Quiz148.run('2 2 ^ 2 ^') == '(2 ^ 2) ^ 2' puts Quiz148.run('2 2 2 ^ ^') == '2 ^ 2 ^ 2' else puts Quiz148.run(ARGV) end end