public static bool TryParseNode(IParser parser, out PrintStatement node, ReportBlockNode reportNode) { node = null; bool result = false; if (parser.PeekToken(TokenKind.PrintKeyword)) { result = true; node = new PrintStatement(); parser.NextToken(); node.StartIndex = parser.Token.Span.Start; node.WhereExpressions = new List <ExpressionNode>(); node.ColumnExpressions = new List <ExpressionNode>(); node.VariableNames = new List <ExpressionNode>(); node.Filenames = new List <ExpressionNode>(); node.OtherExpressions = new List <ExpressionNode>(); TokenKind nextTokKind = parser.PeekToken().Kind; if (ReportStatementFactory.StatementStartKeywords.Contains(nextTokKind) || Genero4glAst.ValidStatementKeywords.Contains(nextTokKind) || parser.PeekToken(TokenKind.OnKeyword) || parser.PeekToken(TokenKind.EveryKeyword) || (parser.PeekToken(TokenKind.FirstKeyword) && parser.PeekToken(TokenKind.PageKeyword, 2)) || parser.PeekToken(TokenKind.PageKeyword) || parser.PeekToken(TokenKind.BeforeKeyword) || parser.PeekToken(TokenKind.AfterKeyword)) { node.EndIndex = parser.Token.Span.End; return(true); } List <TokenKind> breaks = new List <TokenKind> { TokenKind.Comma }; while (true) { if (parser.PeekToken(TokenKind.GroupKeyword)) { parser.NextToken(); } switch (parser.PeekToken().Kind) { case TokenKind.PagenoKeyword: case TokenKind.LinenoKeyword: parser.NextToken(); if (parser.PeekToken(TokenKind.UsingKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenCategory.StringLiteral)) { parser.NextToken(); } if (parser.PeekToken(TokenKind.ClippedKeyword)) { parser.NextToken(); } } break; case TokenKind.ColumnKeyword: { parser.NextToken(); ExpressionNode colExpr; if (FglExpressionNode.TryGetExpressionNode(parser, out colExpr, breaks)) { node.ColumnExpressions.Add(colExpr); } break; } case TokenKind.CountKeyword: case TokenKind.PercentKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); if (parser.PeekToken(TokenKind.Multiply)) { parser.NextToken(); if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in print statement."); } } else { parser.ReportSyntaxError("Expected '*' in print statement."); } } else { parser.ReportSyntaxError("Expected left-paren in print statement."); } if (parser.PeekToken(TokenKind.WhereKeyword)) { parser.NextToken(); ExpressionNode whereClause; if (FglExpressionNode.TryGetExpressionNode(parser, out whereClause, breaks)) { node.WhereExpressions.Add(whereClause); } } if (parser.PeekToken(TokenKind.UsingKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenCategory.StringLiteral)) { parser.NextToken(); } if (parser.PeekToken(TokenKind.ClippedKeyword)) { parser.NextToken(); } } break; } case TokenKind.SumKeyword: case TokenKind.MinKeyword: case TokenKind.MaxKeyword: case TokenKind.AvgKeyword: { parser.NextToken(); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); ExpressionNode varName; if (FglExpressionNode.TryGetExpressionNode(parser, out varName)) { node.VariableNames.Add(varName); if (parser.PeekToken(TokenKind.RightParenthesis)) { parser.NextToken(); } else { parser.ReportSyntaxError("Expected right-paren in print statement."); } } else { parser.ReportSyntaxError("Invalid variable name found in print statement."); } } else { parser.ReportSyntaxError("Expected left-paren in print statement."); } if (parser.PeekToken(TokenKind.WhereKeyword)) { parser.NextToken(); ExpressionNode whereClause; if (FglExpressionNode.TryGetExpressionNode(parser, out whereClause, breaks)) { node.WhereExpressions.Add(whereClause); } } if (parser.PeekToken(TokenKind.UsingKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenCategory.StringLiteral)) { parser.NextToken(); } if (parser.PeekToken(TokenKind.ClippedKeyword)) { parser.NextToken(); } } break; } case TokenKind.FileKeyword: { parser.NextToken(); ExpressionNode filename; if (FglExpressionNode.TryGetExpressionNode(parser, out filename, breaks)) { node.Filenames.Add(filename); } break; } default: { ExpressionNode expr; if (FglExpressionNode.TryGetExpressionNode(parser, out expr, breaks, new ExpressionParsingOptions { AllowStarParam = true, AdditionalExpressionParsers = new ExpressionParser[] { (x) => ReportStatementFactory.ParseAggregateReportFunction(x, reportNode) } })) { node.OtherExpressions.Add(expr); if (parser.PeekToken(TokenKind.SpacesKeyword)) { parser.NextToken(); } else if (parser.PeekToken(TokenKind.WordwrapKeyword)) { parser.NextToken(); if (parser.PeekToken(TokenKind.RightKeyword) && parser.PeekToken(TokenKind.MarginKeyword, 2)) { parser.NextToken(); parser.NextToken(); if (FglExpressionNode.TryGetExpressionNode(parser, out expr, breaks)) { node.OtherExpressions.Add(expr); } else { parser.ReportSyntaxError("Invalid expression found in print statement."); } } } } break; } } var tokKind = parser.PeekToken().Kind; if (tokKind == TokenKind.Comma) { parser.NextToken(); } else if (tokKind == TokenKind.Semicolon) { parser.NextToken(); break; } else if (tokKind >= TokenKind.FirstOperator && tokKind <= TokenKind.LastOperator) { parser.NextToken(); } else { break; } } node.EndIndex = parser.Token.Span.End; } return(result); }
public static bool TryParseNode(Genero4glParser parser, out ReportFormatSection node, IModuleResult containingModule, ReportBlockNode reportNode, Action <PrepareStatement> prepStatementBinder = null, Func <ReturnStatement, ParserResult> returnStatementBinder = null, Action <IAnalysisResult, int, int> limitedScopeVariableAdder = null, List <TokenKind> validExitKeywords = null, IEnumerable <ContextStatementFactory> contextStatementFactories = null) { node = null; bool result = false; if (parser.PeekToken(TokenKind.FormatKeyword)) { parser.NextToken(); result = true; node = new ReportFormatSection(); node.StartIndex = parser.Token.Span.Start; bool isValid = true; while (isValid) { if (parser.PeekToken(TokenKind.EveryKeyword) && parser.PeekToken(TokenKind.RowKeyword, 2)) { parser.NextToken(); parser.NextToken(); node._canOutline = false; } else { node._canOutline = true; switch (parser.PeekToken().Kind) { case TokenKind.FirstKeyword: parser.NextToken(); if (parser.PeekToken(TokenKind.PageKeyword) && parser.PeekToken(TokenKind.HeaderKeyword, 2)) { parser.NextToken(); parser.NextToken(); if (node.DecoratorEnd == 0) { node.DecoratorEnd = parser.Token.Span.End; } } else { parser.ReportSyntaxError("Expected \"page header\" in format section of report."); } break; case TokenKind.PageKeyword: parser.NextToken(); if (parser.PeekToken(TokenKind.HeaderKeyword)) { parser.NextToken(); if (node.DecoratorEnd == 0) { node.DecoratorEnd = parser.Token.Span.End; } } else if (parser.PeekToken(TokenKind.TrailerKeyword)) { parser.NextToken(); if (node.DecoratorEnd == 0) { node.DecoratorEnd = parser.Token.Span.End; } } else { parser.ReportSyntaxError("Expected \"header\" or \"trailer\" in format section of report."); } break; case TokenKind.OnKeyword: parser.NextToken(); if ((parser.PeekToken(TokenKind.EveryKeyword) || parser.PeekToken(TokenKind.LastKeyword)) && parser.PeekToken(TokenKind.RowKeyword, 2)) { parser.NextToken(); parser.NextToken(); if (node.DecoratorEnd == 0) { node.DecoratorEnd = parser.Token.Span.End; } } else { parser.ReportSyntaxError("Expected \"every row\" or \"last row\" in format section of report."); } break; case TokenKind.BeforeKeyword: case TokenKind.AfterKeyword: parser.NextToken(); if (parser.PeekToken(TokenKind.GroupKeyword) && parser.PeekToken(TokenKind.OfKeyword, 2)) { parser.NextToken(); parser.NextToken(); // TODO: get report variable FglNameExpression name; if (FglNameExpression.TryParseNode(parser, out name)) { node.ReportVariable = name; } else { parser.ReportSyntaxError("Invalid name expression found in format section of report."); } if (node.DecoratorEnd == 0) { node.DecoratorEnd = parser.Token.Span.End; } } else { parser.ReportSyntaxError("Expected \"group of\" in format section of report."); } break; default: isValid = false; break; } if (isValid) { // collect statements FglStatement rptStmt; while (ReportStatementFactory.TryGetStatement(parser, out rptStmt, containingModule, reportNode, new List <Func <PrepareStatement, bool> >(), returnStatementBinder, limitedScopeVariableAdder, validExitKeywords) && rptStmt != null) { if (rptStmt.StartIndex < 0) { continue; } node.Children.Add(rptStmt.StartIndex, rptStmt); } } } node.EndIndex = parser.Token.Span.End; } } return(result); }