Ejemplo n.º 1
0
        /**
         * Adds operands to this item
         */
        public void add(ParseItem n)
        {
            n.setParent(this);

            // Grow the array
            ParseItem[] newOperands = new ParseItem[operands.Length + 1];
            System.Array.Copy(operands,0,newOperands,0,operands.Length);
            newOperands[operands.Length] = n;
            operands = newOperands;
        }
Ejemplo n.º 2
0
        /**
         * Adds operands to this item
         */
        public void add(ParseItem n)
        {
            n.setParent(this);

            // Grow the array
            ParseItem[] newOperands = new ParseItem[operands.Length + 1];
            System.Array.Copy(operands, 0, newOperands, 0, operands.Length);
            newOperands[operands.Length] = n;
            operands = newOperands;
        }
Ejemplo n.º 3
0
        /**
         * Recursively parses the token array.  Recursion is used in order
         * to evaluate parentheses and function arguments
         *
         * @param iterator an iterator of tokens
         * @return the root node of the current parse stack
         * @exception FormulaException if an error occurs
         */
        private ParseItem parseCurrent(IEnumerator <ParseItem> iterator)
        {
            Stack <ParseItem> stack     = new Stack <ParseItem>();
            Stack <Operator>  operators = new Stack <Operator>();
            Stack <ParseItem> args      = null;       // we usually don't need this

            bool      parenthesesClosed = false;
            ParseItem lastParseItem     = null;

            while (!parenthesesClosed && iterator.MoveNext())
            {
                ParseItem pi = iterator.Current;
                if (pi == null)
                {
                    break;
                }

                pi.setParseContext(parseContext);

                if (pi is Operand)
                {
                    handleOperand((Operand)pi, stack);
                }
                else if (pi is StringFunction)
                {
                    handleFunction((StringFunction)pi, iterator, stack);
                }
                else if (pi is Operator)
                {
                    Operator op = (Operator)pi;

                    // See if the operator is a binary or unary operator
                    // It is a unary operator either if the stack is empty, or if
                    // the last thing off the stack was another operator
                    if (op is StringOperator)
                    {
                        StringOperator sop = (StringOperator)op;
                        if (stack.Count == 0 || lastParseItem is Operator)
                        {
                            op = sop.getUnaryOperator();
                        }
                        else
                        {
                            op = sop.getBinaryOperator();
                        }
                    }

                    if (operators.Count == 0)
                    {
                        // nothing much going on, so do nothing for the time being
                        operators.Push(op);
                    }
                    else
                    {
                        Operator op2 = operators.Peek();

                        // If the last  operator has a higher precedence then add this to
                        // the operator stack and wait
                        if (op2.getPrecedence() < op2.getPrecedence())
                        {
                            operators.Push(op2);
                        }
                        else if (op2.getPrecedence() == op2.getPrecedence() && op2 is UnaryOperator)
                        {
                            // The operators are of equal precedence, but because it is a
                            // unary operator the operand isn't available yet, so put it on
                            // the stack
                            operators.Push(op2);
                        }
                        else
                        {
                            // The operator is of a lower precedence so we can sort out
                            // some of the items on the stack
                            operators.Pop();                             // remove the operator from the stack
                            op2.getOperands(stack);
                            stack.Push(op2);
                            operators.Push(op2);
                        }
                    }
                }
                else if (pi is ArgumentSeparator)
                {
                    // Clean up any remaining items on this stack
                    while (operators.Count > 0)
                    {
                        Operator o = operators.Pop();
                        o.getOperands(stack);
                        stack.Push(o);
                    }

                    // Add it to the argument stack.  Create the argument stack
                    // if necessary.  Items will be stored on the argument stack in
                    // reverse order
                    if (args == null)
                    {
                        args = new Stack <ParseItem>();
                    }

                    args.Push(stack.Pop());
                    stack.Clear();
                }
                else if (pi is OpenParentheses)
                {
                    ParseItem   pi2 = parseCurrent(iterator);
                    Parenthesis p   = new Parenthesis();
                    pi2.setParent(p);
                    p.add(pi2);
                    stack.Push(p);
                }
                else if (pi is CloseParentheses)
                {
                    parenthesesClosed = true;
                }

                lastParseItem = pi;
            }

            while (operators.Count > 0)
            {
                Operator o = operators.Pop();
                o.getOperands(stack);
                stack.Push(o);
            }

            ParseItem rt = (stack.Count > 0) ? (ParseItem)stack.Pop() : null;

            // if the argument stack is not null, then add it to that stack
            // as well for good measure
            if (args != null && rt != null)
            {
                args.Push(rt);
            }

            arguments = args;

            if (stack.Count > 0 || operators.Count > 0)
            {
                //logger.warn("Formula " + formula + " has a non-empty parse stack");
            }

            return(rt);
        }