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)); }
/// <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); }
private Boolean TryAndResolveIssues(ParsingContext xoContext) { // We can scan the next tokens Leading Trivia // And the last token's trailing trivia for a keyword if (ResolutionGenerator.ScanSurroundingTriviaForKeyword(xoContext)) { // Found a solution, keep processing return(true); } return(false); }
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)); }
private static CanConsumeResult ConcatCanConsume(ParsingContext xoContext, Boolean xbIsPreconsumption = false) { // Intermediate var SyntaxKind oKind = xoContext.List.Peek().ExpectedType; // Consume immediately if (xoContext.CurrentNode.Count <= 1) { if (SyntaxKindFacts.IsIdentifierOrExpression(oKind)) { return(CanConsumeResult.Consume); } else { ResolutionGenerator.HandleIncompleteNode(xoContext); return(CanConsumeResult.Complete); } } // Get BARBAR, consume next else if (oKind == SyntaxKind.BarBarToken) { // Drop the bar bar and consume the next item xoContext.List.Pop(); if (SyntaxKindFacts.IsIdentifierOrExpression(xoContext.List.Peek().ExpectedType)) { return(CanConsumeResult.Consume); } else { ResolutionGenerator.HandleIncompleteNode(xoContext); return(CanConsumeResult.Complete); } } // Else close this object else { // Post consumption check if (xoContext.CurrentNode.Count <= 1) { ResolutionGenerator.HandleIncompleteNode(xoContext); } return(CanConsumeResult.Complete); } }
/// <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); } }