示例#1
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].TokenCount;
     }
     if (_isIf)
     {
         // there will be 2 or 3 extra tAttr Tokens according To whether the false param is present
         tokenCount += children.Length;
     }
     _tokenCount = tokenCount;
 }
        /**
         * Traverses the supplied formula parse tree, calling <c>Ptg.SetClass()</c> for each non-base
         * Token To Set its operand class.
         */
        public void TransformFormula(ParseNode rootNode)
        {
            byte rootNodeOperandClass;
            switch (_formulaType)
            {
                case FormulaType.CELL:
                    rootNodeOperandClass = Ptg.CLASS_VALUE;
                    break;
                case FormulaType.ARRAY:
                    rootNodeOperandClass = Ptg.CLASS_ARRAY;
                    break;
                case FormulaType.NAMEDRANGE:
                case FormulaType.DATAVALIDATION_LIST:
                    rootNodeOperandClass = Ptg.CLASS_REF;
                    break;
                default:
                    throw new Exception("Incomplete code - formula type ("
                            + _formulaType + ") not supported yet");

            }
            TransformNode(rootNode, rootNodeOperandClass, false);
        }
        /**
         * @param callerForceArrayFlag <c>true</c> if one of the current node's parents is a 
         * function Ptg which Has been Changed from default 'V' To 'A' type (due To requirements on
         * the function return value).
         */
        private void TransformNode(ParseNode node, byte desiredOperandClass,
                bool callerForceArrayFlag)
        {
            Ptg token = node.GetToken();
            ParseNode[] children = node.GetChildren();
            bool IsSimpleValueFunc = IsSimpleValueFunction(token);

            if (IsSimpleValueFunc)
            {
                bool localForceArray = desiredOperandClass == Ptg.CLASS_ARRAY;
                for (int i = 0; i < children.Length; i++)
                {
                    TransformNode(children[i], desiredOperandClass, localForceArray);
                }
                SetSimpleValueFuncClass((AbstractFunctionPtg)token, desiredOperandClass, callerForceArrayFlag);
                return;
            }
		if (IsSingleArgSum(token)) {
			// Need to process the argument of SUM with transformFunctionNode below
			// so make a dummy FuncVarPtg for that call.
			token = FuncVarPtg.SUM;
			// Note - the tAttrSum token (node.getToken()) is a base
			// token so does not need to have its operand class set
		}
            if (token is ValueOperatorPtg || token is ControlPtg
                || token is MemFuncPtg
				|| token is MemAreaPtg
				|| token is UnionPtg)
            {
                // Value Operator Ptgs and Control are base Tokens, so Token will be unchanged
                // but any child nodes are processed according To desiredOperandClass and callerForceArrayFlag

                // As per OOO documentation Sec 3.2.4 "Token Class Transformation", "Step 1"
                // All direct operands of value operators that are initially 'R' type will 
                // be converted To 'V' type.
                byte localDesiredOperandClass = desiredOperandClass == Ptg.CLASS_REF ? Ptg.CLASS_VALUE : desiredOperandClass;
                for (int i = 0; i < children.Length; i++)
                {
                    TransformNode(children[i], localDesiredOperandClass, callerForceArrayFlag);
                }
                return;
            }
            if (token is AbstractFunctionPtg)
            {
                TransformFunctionNode((AbstractFunctionPtg)token, children, desiredOperandClass, callerForceArrayFlag);
                return;
            }
            if (children.Length > 0)
            {
                //if (token == RangePtg.instance)
                if(token is OperationPtg)
                {
                    // TODO is any Token transformation required under the various ref operators?
                    return;
                }
                throw new InvalidOperationException("Node should not have any children");
            }

            if (token.IsBaseToken)
            {
                // nothing To do
                return;
            }
            token.PtgClass = (TransformClass(token.PtgClass, desiredOperandClass, callerForceArrayFlag));
        }
        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 InvalidOperationException("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);
                                    //								afp.SetClass(Ptg.CLASS_ARRAY);
                                    break;
                                case Ptg.CLASS_VALUE:
                                    afp.PtgClass = (Ptg.CLASS_ARRAY);
                                    break;
                                default:
                                    throw new InvalidOperationException("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 InvalidOperationException("Unexpected operand class ("
                                            + defaultReturnOperandClass + ")");
                            }
                            localForceArrayFlag = false;
                            break;
                        default:
                            throw new InvalidOperationException("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);
            }
        }
示例#5
0
 /**
  * Collects the array of <c>Ptg</c> Tokens for the specified tree.
  */
 public static Ptg[] ToTokenArray(ParseNode rootNode)
 {
     TokenCollector temp = new TokenCollector(rootNode.TokenCount);
     rootNode.CollectPtgs(temp);
     return temp.GetResult();
 }
示例#6
0
        public ParseNode(Ptg token, ParseNode child0, ParseNode child1)
            : this(token, new ParseNode[] { child0, child1, })
        {

        }