private static String infix2postfix(String[] tokens) throws CalcException {       
        double c;
        String token;
        postfix = new StringBuilder();
        opStack = new Stack<Operator>();
        brStack = new Stack<Bracket>();
        intStack = new Stack<Integer>();
        Operator op;
        Bracket br;
        int i, rpos;
        for(i = 0; i < tokens.length; i++) {
            token = tokens[i];           
            if((op = Operator.find(token)) != null) {
                nextOp(op);
            }
            else if((br = Bracket.isOpen(token)) != null) {                        
                opStack.push(Operator.SKP);
                brStack.push(br);
                intStack.push(i);
            }
            else if((br = Bracket.isClosed(token)) != null){
                intStack.push(i);
                nextClosed(br);
            }else 
                try {
                    c = Double.valueOf(token);
                    postfix.append(token); postfix.append(" ");                 
                }catch (NumberFormatException e) {
                    throw new CalcException("Parse Error: " + token);          
                }
        }
        while (!opStack.empty()) {
            op = opStack.pop(); 
            if (op == Operator.SKP) {
                rpos = intStack.pop();
                throw new CalcException(String.format(
                                        "Mismatched Brackets: %s at position %d", 
                                        tokens[rpos], rpos+1 ));
            }                
            postfix.append(op); postfix.append(" ");
        }
        return postfix.toString();
    }