QueryRef QueryParser::endQuery(QueryRef Q) { const char *Extra = Begin; if (!lexWord().empty()) return new InvalidQuery("unexpected extra input: '" + StringRef(Extra, End - Extra) + "'"); return Q; }
QueryParser::LexOrCompleteWord<T> QueryParser::lexOrCompleteWord(StringRef &Word) { Word = lexWord(); size_t WordCompletionPos = StringRef::npos; if (CompletionPos && CompletionPos <= Word.data() + Word.size()) { if (CompletionPos < Word.data()) WordCompletionPos = 0; else WordCompletionPos = CompletionPos - Word.data(); } return LexOrCompleteWord<T>(this, Word, WordCompletionPos); }
QueryRef QueryParser::doParse() { StringRef CommandStr; ParsedQueryKind QKind = lexOrCompleteWord<ParsedQueryKind>(CommandStr) .Case("", PQK_NoOp) .Case("help", PQK_Help) .Case("m", PQK_Match, /*IsCompletion=*/false) .Case("let", PQK_Let) .Case("match", PQK_Match) .Case("set", PQK_Set) .Case("unlet", PQK_Unlet) .Default(PQK_Invalid); switch (QKind) { case PQK_NoOp: return new NoOpQuery; case PQK_Help: return endQuery(new HelpQuery); case PQK_Let: { StringRef Name = lexWord(); if (Name.empty()) return new InvalidQuery("expected variable name"); if (CompletionPos) return completeMatcherExpression(); Diagnostics Diag; ast_matchers::dynamic::VariantValue Value; if (!Parser::parseExpression(StringRef(Begin, End - Begin), nullptr, &QS.NamedValues, &Value, &Diag)) { return makeInvalidQueryFromDiagnostics(Diag); } return new LetQuery(Name, Value); } case PQK_Match: { if (CompletionPos) return completeMatcherExpression(); Diagnostics Diag; Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression( StringRef(Begin, End - Begin), nullptr, &QS.NamedValues, &Diag); if (!Matcher) { return makeInvalidQueryFromDiagnostics(Diag); } return new MatchQuery(*Matcher); } case PQK_Set: { StringRef VarStr; ParsedQueryVariable Var = lexOrCompleteWord<ParsedQueryVariable>(VarStr) .Case("output", PQV_Output) .Case("bind-root", PQV_BindRoot) .Default(PQV_Invalid); if (VarStr.empty()) return new InvalidQuery("expected variable name"); if (Var == PQV_Invalid) return new InvalidQuery("unknown variable: '" + VarStr + "'"); QueryRef Q; switch (Var) { case PQV_Output: Q = parseSetOutputKind(); break; case PQV_BindRoot: Q = parseSetBool(&QuerySession::BindRoot); break; case PQV_Invalid: llvm_unreachable("Invalid query kind"); } return endQuery(Q); } case PQK_Unlet: { StringRef Name = lexWord(); if (Name.empty()) return new InvalidQuery("expected variable name"); return endQuery(new LetQuery(Name, VariantValue())); } case PQK_Invalid: return new InvalidQuery("unknown command: " + CommandStr); } llvm_unreachable("Invalid query kind"); }