Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }