Beispiel #1
0
        /// <summary>
        /// Parses a set of braces from the file.
        /// </summary>
        /// <param name="scope">The current scope.</param>
        /// <param name="ownerDef">(optional) A definition of an object (e.g. function) that owns these braces.</param>
        /// <param name="funcOutliningStart">(optional) To specify a custom outlining region start position. Function use this to get the outlining to appear at the end of the previous line.</param>
        /// <returns>The braces token.</returns>
        public static BracesToken Parse(Scope scope, Definition ownerDef, int funcOutliningStart = -1)
        {
            if (ownerDef != null)
            {
                scope = scope.CloneIndent();
                scope.ReturnDataType = ownerDef.DataType;
            }

            var code = scope.Code;

            if (!code.ReadExact('{'))
            {
                throw new InvalidOperationException("BracesToken.Parse expected next char to be '{'.");
            }
            var openBraceSpan = code.Span;

            var indentScope = scope.CloneIndentNonRoot();

            indentScope.Hint |= ScopeHint.SuppressFunctionDefinition;

            var ret = new BracesToken(scope);

            ret._funcOutliningStart = funcOutliningStart;
            ret._openToken          = new BraceToken(scope, openBraceSpan, ret, true);
            ret.AddToken(ret._openToken);

            while (!code.EndOfFile)
            {
                if (code.ReadExact('}'))
                {
                    ret._closeToken = new BraceToken(scope, code.Span, ret, false);
                    ret.AddToken(ret._closeToken);
                    return(ret);
                }

                var stmt = StatementToken.TryParse(scope);
                if (stmt != null)
                {
                    ret.AddToken(stmt);
                }
            }

            return(ret);
        }
Beispiel #2
0
        public static SelectStatement Parse(Scope parentScope, KeywordToken selectToken)
        {
            var ret   = new SelectStatement(parentScope, selectToken);
            var scope = parentScope.Clone();

            scope.BreakOwner    = ret;
            scope.ContinueOwner = ret;

            var code = scope.Code;

            if (code.ReadStringLiteral())
            {
                ret.AddToken(new StringLiteralToken(scope, code.Span, code.Text));
            }
            if (code.ReadExact('*'))
            {
                ret.AddToken(new OperatorToken(scope, code.Span, "*"));
            }

            if (!code.ReadExactWholeWord("from"))
            {
                return(ret);
            }
            ret.AddToken(new KeywordToken(scope, code.Span, "from"));

            ExtractTableDefinition extractDef = null;

            DkDict.Table table = null;

            if (code.ReadWord())
            {
                if ((table = DkDict.Dict.GetTable(code.Text)) != null)
                {
                    ret.AddToken(new TableToken(scope, code.Span, code.Text, table.Definition));
                }
                else if ((extractDef = scope.DefinitionProvider.GetAny <ExtractTableDefinition>(code.TokenStartPostion, code.Text).FirstOrDefault()) != null)
                {
                    ret.AddToken(new IdentifierToken(scope, code.Span, code.Text, extractDef));
                }
                else
                {
                    ret.AddToken(new UnknownToken(scope, code.Span, code.Text));
                }
            }

            if (code.ReadExactWholeWord("of"))
            {
                ret.AddToken(new KeywordToken(scope, code.Span, "of"));

                if (code.ReadWord())
                {
                    if ((table = DkDict.Dict.GetTable(code.Text)) != null)
                    {
                        ret.AddToken(new TableToken(scope, code.Span, code.Text, table.Definition));
                    }
                    else
                    {
                        ret.AddToken(new UnknownToken(scope, code.Span, code.Text));
                    }
                }
            }
            else if (code.ReadExact(','))
            {
                ret.AddToken(new DelimiterToken(scope, code.Span));

                var expectingComma = false;

                while (!code.EndOfFile)
                {
                    if (code.PeekExact('{'))
                    {
                        break;
                    }
                    if (expectingComma)
                    {
                        if (code.ReadExact(','))
                        {
                            ret.AddToken(new DelimiterToken(scope, code.Span));
                            expectingComma = false;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (code.ReadWord())
                    {
                        if ((table = DkDict.Dict.GetTable(code.Text)) != null)
                        {
                            ret.AddToken(new TableToken(scope, code.Span, code.Text, table.Definition));
                        }
                        else
                        {
                            ret.AddToken(new UnknownToken(scope, code.Span, code.Text));
                        }
                        expectingComma = true;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // WHERE and ORDER BY
            var gotWhere   = false;
            var gotOrderBy = false;

            while (!code.EndOfFile)
            {
                if (code.PeekExact('{'))
                {
                    break;
                }
                if (!gotWhere && code.ReadExactWholeWord("where"))
                {
                    ret.AddToken(new KeywordToken(scope, code.Span, code.Text));
                    gotWhere = true;

                    var exp = ExpressionToken.TryParse(scope, _whereEndTokens);
                    if (exp != null)
                    {
                        ret.AddToken(exp);
                    }
                    else
                    {
                        break;
                    }
                }
                else if (!gotOrderBy && code.ReadExactWholeWord("order"))
                {
                    ret.AddToken(new KeywordToken(scope, code.Span, code.Text));
                    gotOrderBy = true;

                    if (!code.ReadExactWholeWord("by"))
                    {
                        break;
                    }
                    ret.AddToken(new KeywordToken(scope, code.Span, code.Text));

                    while (!code.EndOfFile)
                    {
                        if (code.PeekExact('{'))
                        {
                            break;
                        }

                        if (code.ReadExact(','))
                        {
                            ret.AddToken(new DelimiterToken(scope, code.Span));
                            continue;
                        }

                        if (code.ReadExactWholeWord("asc") || code.ReadExactWholeWord("desc"))
                        {
                            ret.AddToken(new KeywordToken(scope, code.Span, code.Text));
                            continue;
                        }

                        if (TryParseColumn(scope, ret, true, extractDef))
                        {
                            continue;
                        }

                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            // Body
            if (code.ReadExact('{'))
            {
                var braces = new BracesToken(scope);
                braces.AddOpen(code.Span);
                ret.AddToken(braces);

                while (!code.EndOfFile)
                {
                    if (code.ReadExact('}'))
                    {
                        braces.AddClose(code.Span);
                        break;
                    }

                    if (code.ReadExactWholeWord("for"))
                    {
                        braces.AddToken(new KeywordToken(scope, code.Span, "for"));

                        if (!code.ReadExactWholeWord("each"))
                        {
                            continue;
                        }
                        braces.AddToken(new KeywordToken(scope, code.Span, "each"));

                        if (!code.ReadExact(':'))
                        {
                            continue;
                        }
                        braces.AddToken(new OperatorToken(scope, code.Span, ":"));
                    }
                    else if (code.ReadExactWholeWord("before") || code.ReadExactWholeWord("after"))
                    {
                        braces.AddToken(new KeywordToken(scope, code.Span, code.Text));

                        if (!code.ReadExactWholeWord("group"))
                        {
                            continue;
                        }
                        braces.AddToken(new KeywordToken(scope, code.Span, "group"));

                        if (code.ReadExactWholeWord("all"))
                        {
                            braces.AddToken(new KeywordToken(scope, code.Span, "all"));

                            if (!code.ReadExact(':'))
                            {
                                continue;
                            }
                            braces.AddToken(new OperatorToken(scope, code.Span, ":"));
                        }
                        else if (TryParseColumn(scope, braces, false, extractDef))
                        {
                            if (!code.ReadExact(':'))
                            {
                                continue;
                            }
                            braces.AddToken(new OperatorToken(scope, code.Span, ":"));
                        }
                    }
                    else if (code.ReadExactWholeWord("default"))
                    {
                        braces.AddToken(new KeywordToken(scope, code.Span, "default"));

                        if (!code.ReadExact(':'))
                        {
                            continue;
                        }
                        braces.AddToken(new OperatorToken(scope, code.Span, ":"));
                    }
                    else
                    {
                        var stmt = StatementToken.TryParse(scope);
                        if (stmt != null)
                        {
                            braces.AddToken(stmt);
                        }
                    }
                }
            }

            return(ret);
        }