private void TransformNode(ParseNode node, byte desiredOperandClass,
                bool callerForceArrayFlag)
        {
            Ptg token = node.GetToken();
            ParseNode[] children = node.Children;
            if (token is ValueOperatorPtg || token is ControlPtg)
            {
                // Value Operator Ptgs and Control are base tokens, so token will be UnChanged

                // but any child nodes are Processed according to desiredOperandClass and callerForceArrayFlag
                for (int i = 0; i < children.Length; i++)
                {
                    ParseNode child = children[i];
                    TransformNode(child, desiredOperandClass, callerForceArrayFlag);
                }
                return;
            }
            if (token is AbstractFunctionPtg)
            {
                TransformFunctionNode((AbstractFunctionPtg)token, children, desiredOperandClass,
                        callerForceArrayFlag);
                return;
            }
            if (children.Length > 0)
            {
                throw new Exception("Node should not have any children");
            }

            if (token.IsBaseToken)
            {
                // nothing to do
                return;
            }
            if (callerForceArrayFlag)
            {
                switch (desiredOperandClass)
                {
                    case Ptg.CLASS_VALUE:
                    case Ptg.CLASS_ARRAY:
                        token.PtgClass=(Ptg.CLASS_ARRAY);
                        break;
                    case Ptg.CLASS_REF:
                        token.PtgClass=(Ptg.CLASS_REF);
                        break;
                    default:
                        throw new Exception("Unexpected operand class ("
                                + desiredOperandClass + ")");
                }
            }
            else
            {
                token.PtgClass=(desiredOperandClass);
            }
        }
        /**
         * Traverses the supplied formula parse tree, calling <tt>Ptg.SetClass()</tt> for each non-base
         * token to Set its operand class.
         */
        public void TransformFormula(ParseNode rootNode)
        {
            byte rootNodeOperandClass;
            switch (_formulaType)
            {
                case FormulaParser.FORMULA_TYPE_CELL:
                    rootNodeOperandClass = Ptg.CLASS_VALUE;
                    break;
                default:
                    throw new Exception("Incomplete code - formula type ("
                            + _formulaType + ") not supported yet");

            }
            TransformNode(rootNode, rootNodeOperandClass, false);
        }
Example #3
0
 public ParseNode(Ptg token, ParseNode[] children)
 {
     _token = token;
     _children = children;
     _isIf = IsIf(token);
     int tokenCount = 1;
     for (int i = 0; i < children.Length; i++)
     {
         tokenCount += children[i].GetTokenCount();
     }
     if (_isIf)
     {
         // there will be 2 or 3 extra tAttr tokens according to whether the false param is present
         tokenCount += children.Length;
     }
     _tokenCount = tokenCount;
 }
        private void TransformFunctionNode(AbstractFunctionPtg afp, ParseNode[] children,
                byte desiredOperandClass, bool callerForceArrayFlag)
        {

            bool localForceArrayFlag;
            byte defaultReturnOperandClass = afp.DefaultOperandClass;

            if (callerForceArrayFlag)
            {
                switch (defaultReturnOperandClass)
                {
                    case Ptg.CLASS_REF:
                        if (desiredOperandClass == Ptg.CLASS_REF)
                        {
                            afp.PtgClass=(Ptg.CLASS_REF);
                        }
                        else
                        {
                            afp.PtgClass=(Ptg.CLASS_ARRAY);
                        }
                        localForceArrayFlag = false;
                        break;
                    case Ptg.CLASS_ARRAY:
                        afp.PtgClass=(Ptg.CLASS_ARRAY);
                        localForceArrayFlag = false;
                        break;
                    case Ptg.CLASS_VALUE:
                        afp.PtgClass=(Ptg.CLASS_ARRAY);
                        localForceArrayFlag = true;
                        break;
                    default:
                        throw new Exception("Unexpected operand class ("
                                + defaultReturnOperandClass + ")");
                }
            }
            else
            {
                if (defaultReturnOperandClass == desiredOperandClass)
                {
                    localForceArrayFlag = false;
                    // an alternative would have been to for non-base Ptgs to Set their operand class 
                    // from their default, but this would require the call in many subclasses because
                    // the default OC Is not known Until the end of the constructor
                    afp.PtgClass=(defaultReturnOperandClass);
                }
                else
                {
                    switch (desiredOperandClass)
                    {
                        case Ptg.CLASS_VALUE:
                            // always OK to Set functions to return 'value'
                            afp.PtgClass=(Ptg.CLASS_VALUE);
                            localForceArrayFlag = false;
                            break;
                        case Ptg.CLASS_ARRAY:
                            switch (defaultReturnOperandClass)
                            {
                                case Ptg.CLASS_REF:
                                    afp.PtgClass=(Ptg.CLASS_REF);
                                    break;
                                case Ptg.CLASS_VALUE:
                                    afp.PtgClass=(Ptg.CLASS_ARRAY);
                                    break;
                                default:
                                    throw new Exception("Unexpected operand class ("
                                            + defaultReturnOperandClass + ")");
                            }
                            localForceArrayFlag = (defaultReturnOperandClass == Ptg.CLASS_VALUE);
                            break;
                        case Ptg.CLASS_REF:
                            switch (defaultReturnOperandClass)
                            {
                                case Ptg.CLASS_ARRAY:
                                    afp.PtgClass=(Ptg.CLASS_ARRAY);
                                    break;
                                case Ptg.CLASS_VALUE:
                                    afp.PtgClass=(Ptg.CLASS_VALUE);
                                    break;
                                default:
                                    throw new Exception("Unexpected operand class ("
                                            + defaultReturnOperandClass + ")");
                            }
                            localForceArrayFlag = false;
                            break;
                        default:
                            throw new Exception("Unexpected operand class ("
                                    + desiredOperandClass + ")");
                    }

                }
            }

            for (int i = 0; i < children.Length; i++)
            {
                ParseNode child = children[i];
                byte paramOperandClass = afp.GetParameterClass(i);
                TransformNode(child, paramOperandClass, localForceArrayFlag);
            }
        }
Example #5
0
 /// <summary>
 /// Collects the array of Ptg
 ///  tokens for the specified tree.
 /// </summary>
 /// <param name="rootNode">The root node.</param>
 /// <returns></returns>
 public static Ptg[] ToTokenArray(ParseNode rootNode)
 {
     TokenCollector temp = new TokenCollector(rootNode.GetTokenCount());
     rootNode.CollectPtgs(temp);
     return temp.Result;
 }
Example #6
0
 public ParseNode(Ptg token, ParseNode child0, ParseNode child1): this(token, new ParseNode[] { child0, child1, })
 {
    
 }
        //{--------------------------------------------------------------}
        //{ Parse and Translate an Assignment Statement }
        /**
    procedure Assignment;
    var Name: string[8];
    begin
       Name := GetName;
       Match('=');
       Expression;

    end;
         **/


        /**
         *  API call To execute the parsing of the formula
         * @deprecated use Ptg[] FormulaParser.Parse(String, HSSFWorkbook) directly
         */
        public void Parse()
        {
            pointer = 0;
            GetChar();
            _rootNode = comparisonExpression();

            if (pointer <= formulaLength)
            {
                String msg = "Unused input [" + formulaString.Substring(pointer - 1)
                    + "] after attempting To Parse the formula [" + formulaString + "]";
                throw new FormulaParseException(msg);
            }
        }
 private ParseNode concatExpression()
 {
     ParseNode result = AdditiveExpression();
     while (true)
     {
         SkipWhite();
         if (look != '&')
         {
             break; // finished with concat expression
         }
         Match('&');
         ParseNode other = AdditiveExpression();
         result = new ParseNode(ConcatPtg.instance, result, other);
     }
     return result;
 }
 /** Parse and Translate an Expression */
 private ParseNode AdditiveExpression()
 {
     ParseNode result = Term();
     while (true)
     {
         SkipWhite();
         Ptg operator1;
         switch (look)
         {
             case '+':
                 Match('+');
                 operator1 = AddPtg.instance;
                 break;
             case '-':
                 Match('-');
                 operator1 = SubtractPtg.instance;
                 break;
             default:
                 return result; // finished with Additive expression
         }
         ParseNode other = Term();
         result = new ParseNode(operator1, result, other);
     }
 }
Example #10
0
 private ParseNode comparisonExpression()
 {
     ParseNode result = concatExpression();
     while (true)
     {
         SkipWhite();
         switch (look)
         {
             case '=':
             case '>':
             case '<':
                 Ptg comparisonToken = GetComparisonToken();
                 ParseNode other = concatExpression();
                 result = new ParseNode(comparisonToken, result, other);
                 continue;
         }
         return result; // finished with predicate expression
     }
 }
Example #11
0
 /** Parse and Translate a Math Term */
 private ParseNode Term()
 {
     ParseNode result = powerFactor();
     while (true)
     {
         SkipWhite();
         Ptg operator1;
         switch (look)
         {
             case '*':
                 Match('*');
                 operator1 = MultiplyPtg.instance;
                 break;
             case '/':
                 Match('/');
                 operator1 = DividePtg.instance;
                 break;
             default:
                 return result; // finished with Term
         }
         ParseNode other = powerFactor();
         result = new ParseNode(operator1, result, other);
     }
 }
Example #12
0
 private ParseNode percentFactor()
 {
     ParseNode result = ParseSimpleFactor();
     while (true)
     {
         SkipWhite();
         if (look != '%')
         {
             return result;
         }
         Match('%');
         result = new ParseNode(PercentPtg.instance, result);
     }
 }
Example #13
0
 /** Parse and Translate a Math Factor  */
 private ParseNode powerFactor()
 {
     ParseNode result = percentFactor();
     while (true)
     {
         SkipWhite();
         if (look != '^')
         {
             return result;
         }
         Match('^');
         ParseNode other = percentFactor();
         result = new ParseNode(PowerPtg.instance, result, other);
     }
 }
Example #14
0
        /**
         * Generates the variable function ptg for the formula.
         * <p>
         * For IF Formulas, Additional PTGs are Added To the Tokens
         * @param name
         * @param numArgs
         * @return Ptg a null Is returned if we're in an IF formula, it needs extreme manipulation and Is handled in this function
         */
        private ParseNode GetFunction(String name, NamePtg namePtg, ParseNode[] args)
        {

            FunctionMetadata fm = FunctionMetadataRegistry.GetFunctionByName(name.ToUpper());
            int numArgs = args.Length;
            if (fm == null)
            {
                if (namePtg == null)
                {
                    throw new InvalidOperationException("NamePtg must be supplied for external functions");
                }
                // must be external function
                ParseNode[] allArgs = new ParseNode[numArgs + 1];
                allArgs[0] = new ParseNode(namePtg);
                Array.Copy(args, 0, allArgs, 1, numArgs);
                return new ParseNode(new FuncVarPtg(name, (byte)(numArgs + 1)), allArgs);
            }

            if (namePtg != null)
            {
                throw new InvalidOperationException("NamePtg no applicable To internal functions");
            }
            bool IsVarArgs = !fm.HasFixedArgsLength;
            int funcIx = fm.Index;
            ValidateNumArgs(args.Length, fm);

            AbstractFunctionPtg retval;
            if (IsVarArgs)
            {
                retval = new FuncVarPtg(name, (byte)numArgs);
            }
            else
            {
                retval = new FuncPtg(funcIx);
            }
            return new ParseNode(retval, args);
        }