public static SwitchStatement Parse(Scope scope, KeywordToken switchToken) { var ret = new SwitchStatement(scope, switchToken); scope = scope.Clone(); scope.BreakOwner = ret; var code = scope.Code; var expressionScope = scope.Clone(); expressionScope.Hint |= ScopeHint.SuppressDataType | ScopeHint.SuppressFunctionDefinition | ScopeHint.SuppressVarDecl; ret._expressionToken = ExpressionToken.TryParse(expressionScope, null); if (ret._expressionToken != null) { ret.AddToken(ret._expressionToken); } if (code.ReadExact('{')) { var bodyScope = scope.Clone(); bodyScope.Hint |= ScopeHint.SuppressFunctionDefinition; ret._bodyToken = new BracesToken(bodyScope, code.Span); ret.AddToken(ret._bodyToken); var switchDataType = ret.ExpressionDataType; while (true) { if (code.ReadExact('}')) { ret._bodyToken.AddClose(code.Span); return(ret); } if (code.ReadExactWholeWord("case")) { ret.AddToken(new KeywordToken(scope, code.Span, "case")); var caseExp = ExpressionToken.TryParse(scope, _caseEndTokens, expectedDataType: switchDataType); if (caseExp != null) { ret.AddToken(caseExp); } if (code.ReadExact(':')) { ret.AddToken(new OperatorToken(scope, code.Span, ":")); } continue; } if (code.ReadExactWholeWord("default")) { ret.AddToken(new KeywordToken(scope, code.Span, "default")); if (code.ReadExact(':')) { ret.AddToken(new OperatorToken(scope, code.Span, ":")); } continue; } var stmt = StatementToken.TryParse(bodyScope); if (stmt != null) { ret._bodyToken.AddToken(stmt); } else { break; } } } return(ret); }
public static ArgsToken ParseAndChooseArguments(Scope scope, OperatorToken openBracketToken, Definition[] sigDefs, out Definition selectedDef) { #if DEBUG if (sigDefs == null) { throw new ArgumentNullException("sigDefs"); } if (sigDefs.Length == 0) { throw new ArgumentException("sigDefs must contain at least one signature definition."); } #endif if (sigDefs.Length == 1) { selectedDef = sigDefs[0]; return(Parse(scope, openBracketToken, sigDefs[0].ArgumentsSignature)); } var code = scope.Code; var ret = new ArgsToken(scope, openBracketToken); scope = scope.Clone(); scope.Hint |= ScopeHint.SuppressStatementStarts; var tokens = new List <Token>(); var dataTypes = new List <DataType>(); List <Token> bestTokens = null; var bestConfidence = 0.0f; Definition bestSigDef = null; var codeResetPos = code.Position; foreach (var sigDef in sigDefs) { var args = sigDef.Arguments.ToArray(); var argIndex = 0; var expectingDataType = true; tokens.Clear(); dataTypes.Clear(); code.Position = codeResetPos; while (code.SkipWhiteSpace()) { code.Peek(); if (code.Text == ")") { tokens.Add(new OperatorToken(scope, code.MovePeekedSpan(), ")")); ret._terminated = true; break; } else if (code.Text == ",") { tokens.Add(new OperatorToken(scope, code.MovePeekedSpan(), ",")); argIndex++; expectingDataType = true; continue; } var exp = ExpressionToken.TryParse(scope, _endTokens, expectedDataType: argIndex < args.Length ? args[argIndex].DataType : null); if (exp != null) { tokens.Add(exp); if (expectingDataType) { dataTypes.Add(exp.ValueDataType); } expectingDataType = false; } else { break; } } if (dataTypes.Count == args.Length) { var confidence = 1.0f; for (int i = 0, ii = args.Length; i < ii; i++) { confidence *= DataType.CalcArgumentCompatibility(args[i].DataType, dataTypes[i]); } if (confidence > bestConfidence) { bestConfidence = confidence; bestTokens = tokens; bestSigDef = sigDef; } } else if (bestTokens == null) { bestTokens = tokens; bestConfidence = 0.0f; bestSigDef = sigDef; } } ret.AddTokens(bestTokens); ret._sig = bestSigDef.ArgumentsSignature; ret._sigAlternatives = (from s in sigDefs where s.ArgumentsSignature != ret._sig select s.ArgumentsSignature).ToArray(); selectedDef = bestSigDef; 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); }
public static BracketsToken Parse(Scope scope, DataType expectedDataType) { var code = scope.Code; if (!code.ReadExact('(')) { throw new InvalidOperationException("BracketsToken.Parse expected next char to be '('."); } var openBracketSpan = code.Span; var indentScope = scope.CloneIndentNonRoot(); indentScope.Hint |= ScopeHint.SuppressFunctionDefinition | ScopeHint.SuppressControlStatements | ScopeHint.SuppressStatementStarts; var ret = new BracketsToken(scope); ret.AddToken(ret._openToken = new OpenBracketToken(scope, openBracketSpan, ret)); List <Token> dataTypeTokens = null; var dataType = DataType.TryParse(new DataType.ParseArgs { Code = code, Scope = scope, DataTypeCallback = name => { return(indentScope.DefinitionProvider.GetAny <Defs.DataTypeDefinition>(openBracketSpan.End, name).FirstOrDefault()); }, VariableCallback = name => { return(indentScope.DefinitionProvider.GetAny <Defs.VariableDefinition>(openBracketSpan.End, name).FirstOrDefault()); }, TableFieldCallback = (tableName, fieldName) => { foreach (var tableDef in indentScope.DefinitionProvider.GetGlobalFromFile(tableName)) { if (tableDef.AllowsChild) { foreach (var fieldDef in tableDef.GetChildDefinitions(fieldName)) { return(new Defs.Definition[] { tableDef, fieldDef }); } } } return(null); }, TokenCreateCallback = token => { if (dataTypeTokens == null) { dataTypeTokens = new List <Token>(); } dataTypeTokens.Add(token); }, VisibleModel = scope.Visible }); if (dataType != null && code.ReadExact(')')) { ret._cast = dataType; if (dataTypeTokens != null) { foreach (var token in dataTypeTokens) { ret.AddToken(token); } } ret.AddToken(ret._closeToken = new CloseBracketToken(scope, code.Span, ret)); } else { while (!code.EndOfFile) { if (code.ReadExact(')')) { ret.AddToken(ret._closeToken = new CloseBracketToken(scope, code.Span, ret)); break; } var exp = ExpressionToken.TryParse(indentScope, _endTokens, expectedDataType: expectedDataType); if (exp != null) { ret._innerTokens.Add(exp); ret.AddToken(exp); } else { break; } } } return(ret); }