示例#1
0
        private static CanConsumeResult JoinCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false)
        {
            SyntaxKind eKind = xoContext.List.Peek().ExpectedType;

            if (SyntaxKindFacts.IsIdentifier(eKind) ||
                eKind == SyntaxKind.OpenParenthesisToken ||
                eKind == SyntaxKind.OnKeyword ||
                (xbIsPreconsumption && SyntaxKindFacts.IsJoinKeyword(eKind)) // Allow preconsumption to use JOIN keywods
                )
            {
                return(CheckIfConsumptionIsAllowed(xoContext));
            }
            // If we got another keyword (that we cant process)
            else if (
                SyntaxKindFacts.IsTerminatingNode(eKind) ||
                SyntaxKindFacts.IsKeyword(eKind) ||
                eKind == SyntaxKind.CloseParenthesisToken)
            {
                // Post execution check
                if (xoContext.CurrentNode.Count != 3)
                {
                    ResolutionGenerator.HandleIncompleteNode(xoContext);
                }

                return(CanConsumeResult.Complete);
            }

            CanConsumeResult eResult = DefaultCanConsumeNext(xoContext);



            return(DefaultCanConsumeNext(xoContext));
        }
示例#2
0
        /// <summary>
        /// Used by WHERE and ON
        /// </summary>
        /// <param name="xoContext.CurrentNode"></param>
        /// <param name="xoContext.List"></param>
        /// <returns></returns>
        private static CanConsumeResult ExpressionCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false)
        {
            SyntaxKind eKind = xoContext.List.Peek().ExpectedType;

            if (
                SyntaxKindFacts.IsIdentifierOrExpression(eKind) ||     // Identifiers and Expressions are allowed here
                SyntaxKindFacts.IsAdjunctConditionalOperator(eKind) || // AND OR
                SyntaxKindFacts.IsConditionalOperator(eKind) ||        // = >= IN
                SyntaxKindFacts.IsUnaryOperator(eKind) ||              // NOT
                SyntaxKindFacts.IsFunction(eKind) ||
                SyntaxKindFacts.IsArithmaticOperator(eKind))
            {
                return(CheckIfConsumptionIsAllowed(xoContext));
            }


            CanConsumeResult eResult = DefaultCanConsumeNext(xoContext);

            // Post execution check
            if (eResult == CanConsumeResult.Complete && xoContext.CurrentNode.Count != 1)
            {
                ResolutionGenerator.HandleIncompleteNode(xoContext);
            }

            return(eResult);
        }
示例#3
0
        private static CanConsumeResult BinaryExpressionCanConsumeNext(ParsingContext xoContext, Boolean xbIsPreconsumption = false)
        {
            // Intermediate var
            SyntaxKind eKind = xoContext.List.Peek().ExpectedType;

            // If we have something we are actually allowed to consume
            if ((xbIsPreconsumption && SyntaxKindFacts.IsAdjunctConditionalOperator(eKind)) || // Allow AND/OR in preconsump
                SyntaxKindFacts.IsIdentifierOrExpression(eKind) ||                             // Identifiers and Expressions are allowed here
                SyntaxKindFacts.IsConditionalOperator(eKind) ||                                // = >= IN
                SyntaxKindFacts.IsUnaryOperator(eKind) ||                                      // NOT
                SyntaxKindFacts.IsArithmaticOperator(eKind))
            {
                CanConsumeResult eResult = CheckIfConsumptionIsAllowed(xoContext);

                switch (eResult)
                {
                // Possible erroroneous
                case CanConsumeResult.Unknown:

                // Definitely finished
                case CanConsumeResult.Complete:
                    // Perform final checks
                    break;

                // Break immediately
                case CanConsumeResult.Skip:
                case CanConsumeResult.Consume:
                    return(eResult);
                }
            }

            // Closing condition
            if (xoContext.CurrentNode.IsFull() ||
                SyntaxKindFacts.IsTerminatingNode(eKind) ||
                SyntaxKindFacts.IsKeyword(eKind) ||
                eKind == SyntaxKind.CloseParenthesisToken)
            {
                // Post execution check
                if (xoContext.CurrentNode.Count != 2)
                {
                    ResolutionGenerator.HandleIncompleteNode(xoContext);
                }

                return(CanConsumeResult.Complete);
            }

            //
            return(DefaultCanConsumeNext(xoContext));
        }
示例#4
0
        /// <summary>
        /// Postprocessing method that can be overriden if some activity needs to be
        /// done immediately after a node is constructed
        /// </summary>
        /// <param name="xoNode"></param>
        /// <param name="xoContext.List"></param>
        /// <returns></returns>
        private Boolean AddChildAndPostProcess(ParsingContext xoContext, Boolean xbIsPreconsumption = false)
        {
            // Is not a node, cannot be added
            if (!xoContext.List.Peek().IsNode())
            {
                return(false);
            }

            SyntaxNode oNewNode = (SyntaxNode)xoContext.List.Pop();

            // Do preconsumption here
            if (SyntaxKindFacts.IsBinaryConstruct(oNewNode.ExpectedType))
            {
                // If there is nothing to preconsume
                if (xoContext.CurrentNode.Count == 0)
                {
                    // Else we have an error to fix
                    ResolutionGenerator.HandlePreconsumptionError(new ParsingContext(oNewNode, xoContext.List));
                }
                // If there is something to preconsume
                else
                {
                    int        iSiblingPosition = xoContext.CurrentNode.Count - 1;
                    SyntaxNode oPrevSibling     = xoContext.CurrentNode[iSiblingPosition];

                    // Put the previous sibling back on the List to be consumed
                    xoContext.List.Insert(oPrevSibling);

                    // Check the eligibility of the previous node
                    CanConsumeResult eEligibility = oNewNode.CanConsumeNode(
                        new ParsingContext(oNewNode, xoContext.List), true);

                    if (eEligibility == CanConsumeResult.Consume)
                    {
                        // Assign the parent
                        oNewNode.Parent = xoContext.CurrentNode;

                        // Pull off the last node from the parent
                        oNewNode.Add((SyntaxNode)xoContext.List.Pop());

                        // Remove it too
                        xoContext.CurrentNode.RemoveAt(iSiblingPosition);
                    }
                    else
                    {
                        // Else we have an error to fix
                        ResolutionGenerator.HandlePreconsumptionError(new ParsingContext(oNewNode, xoContext.List));
                    }
                }
            }

            // If it is full
            if (xoContext.CurrentNode.IsFull())
            {
                return(false);
            }
            else
            {
                // Add the child
                xoContext.CurrentNode.Add(oNewNode);
                // 2. Depth first traversal from the child
                if (oNewNode.TryConsumeFromContext(xoContext))
                {
                    // If it successfully consumed something
                }
                return(true);
            }
        }
示例#5
0
        /// <summary>
        /// This node will try and consume items from the list
        /// </summary>
        /// <param name="xoContext"></param>
        /// <returns></returns>
        public virtual Boolean TryConsumeFromContext(ParsingContext xoContext)
        {
            // Until we break
            while (true)
            {
                // Generate a new context every time
                ParsingContext oContext = new ParsingContext(this, xoContext.List);

                // Call the Consumption fn
                CanConsumeResult eResult = Strategy.EligibilityFn(oContext, false);

                // Switch based on the result of the attempt
                switch (eResult)
                {
                case CanConsumeResult.Consume:
                    // Create a new node
                    ISyntax oNew = Strategy.TryConsumeNextFn(oContext, false);

                    // Append the new node to the list
                    oContext.List.Insert(oNew);

                    // Consume it
                    if (AddChildAndPostProcess(oContext, false))
                    {
                        // Set the variable once
                        if (!bHasConsumedNodes)
                        {
                            bHasConsumedNodes = true;
                        }
                    }
                    else
                    {
                        // Couldn't add the node for some reason
                        this.Comments.Add(new StatusItem("Could not add:" + oNew.RawSQLText));
                    }
                    break;

                case CanConsumeResult.Skip:
                    //xoList.PopToken(); // Skip the next node
                    break;

                case CanConsumeResult.Complete:
                    // If post validation fails and we fixed the issue
                    if (!Strategy.ValidationFn(oContext) && TryAndResolveIssues(oContext))
                    {
                        // keep processing
                        break;
                    }

                    // Else Terminating case
                    return(bHasConsumedNodes);

                case CanConsumeResult.Unknown:
                    // Try and fix any issues
                    if (TryAndResolveIssues(oContext))
                    {
                        // Found a solution, keep processing
                        break;
                    }

                    // Else, fail and leave here
                    return(bHasConsumedNodes);
                }
            }
        }