/// <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); }
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); }