10 #include "llvm/ADT/StringSwitch.h"
18 llvm::StringRef QueryParser::lexWord() {
20 line = line.ltrim(
" \t\v\f\r");
29 if (line.front() ==
'#') {
30 word = line.substr(0, 1);
32 word = line.take_until([](
char c) {
34 return llvm::StringRef(
" \t\v\f\r").contains(c);
38 line = line.drop_front(word.size());
71 bool isCompletion =
true) {
75 else if (!caseStr.empty() && isCompletion &&
82 std::string(caseStr));
91 llvm::StringRef extra = line;
92 llvm::StringRef extraTrimmed = extra.ltrim(
" \t\v\f\r");
94 if ((!extraTrimmed.empty() && extraTrimmed[0] ==
'\n') ||
95 (extraTrimmed.size() >= 2 && extraTrimmed[0] ==
'\r' &&
96 extraTrimmed[1] ==
'\n'))
97 queryRef->remainingContent = extra;
99 llvm::StringRef trailingWord = lexWord();
100 if (!trailingWord.empty() && trailingWord.front() ==
'#') {
101 line = line.drop_until([](
char c) {
return c ==
'\n'; });
102 line = line.drop_while([](
char c) {
return c ==
'\n'; });
103 return endQuery(queryRef);
105 if (!trailingWord.empty()) {
106 return new InvalidQuery(
"unexpected extra input: '" + extra +
"'");
114 enum class ParsedQueryKind {
124 makeInvalidQueryFromDiagnostics(
const matcher::internal::Diagnostics &
diag) {
126 llvm::raw_string_ostream os(errStr);
128 return new InvalidQuery(os.str());
132 QueryRef QueryParser::completeMatcherExpression() {
133 std::vector<matcher::MatcherCompletion> comps =
137 for (
const auto &comp : comps) {
138 completions.emplace_back(comp.typedText, comp.matcherDecl);
145 llvm::StringRef commandStr;
146 ParsedQueryKind qKind =
147 LexOrCompleteWord<ParsedQueryKind>(
this, commandStr)
148 .Case(
"", ParsedQueryKind::NoOp)
149 .Case(
"#", ParsedQueryKind::Comment,
false)
150 .Case(
"help", ParsedQueryKind::Help)
151 .Case(
"m", ParsedQueryKind::Match,
false)
152 .Case(
"match", ParsedQueryKind::Match)
153 .Case(
"q", ParsedQueryKind::Quit,
false)
154 .Case(
"quit", ParsedQueryKind::Quit)
155 .Default(ParsedQueryKind::Invalid);
158 case ParsedQueryKind::Comment:
159 case ParsedQueryKind::NoOp:
160 line = line.drop_until([](
char c) {
return c ==
'\n'; });
161 line = line.drop_while([](
char c) {
return c ==
'\n'; });
163 return new NoOpQuery;
166 case ParsedQueryKind::Help:
167 return endQuery(
new HelpQuery);
169 case ParsedQueryKind::Quit:
170 return endQuery(
new QuitQuery);
172 case ParsedQueryKind::Match: {
174 return completeMatcherExpression();
177 matcher::internal::Diagnostics
diag;
178 auto matcherSource = line.ltrim();
179 auto origMatcherSource = matcherSource;
180 std::optional<matcher::DynMatcher> matcher =
184 return makeInvalidQueryFromDiagnostics(
diag);
186 auto actualSource = origMatcherSource.slice(0, origMatcherSource.size() -
187 matcherSource.size());
188 QueryRef query =
new MatchQuery(actualSource, *matcher);
189 query->remainingContent = matcherSource;
193 case ParsedQueryKind::Invalid:
194 return new InvalidQuery(
"unknown command: " + commandStr);
197 llvm_unreachable(
"Invalid query kind");
204 std::vector<llvm::LineEditor::Completion>
208 queryParser.completionPos = line.data() + pos;
210 queryParser.doParse();
211 return queryParser.completions;
static std::string diag(const llvm::Value &value)
static QueryRef parse(llvm::StringRef line, const QuerySession &qs)
static std::vector< llvm::LineEditor::Completion > complete(llvm::StringRef line, size_t pos, const QuerySession &qs)
const matcher::Registry & getRegistryData() const
llvm::StringMap< matcher::VariantValue > namedValues
static std::vector< MatcherCompletion > completeExpression(llvm::StringRef &code, unsigned completionOffset, const Registry &matcherRegistry, const NamedValueMap *namedValues)
static std::optional< DynMatcher > parseMatcherExpression(llvm::StringRef &matcherCode, const Registry &matcherRegistry, const NamedValueMap *namedValues, Diagnostics *error)
Include the generated interface declarations.
llvm::IntrusiveRefCntPtr< Query > QueryRef
llvm::StringSwitch< T > stringSwitch
QueryParser * queryParser
LexOrCompleteWord(QueryParser *queryParser, llvm::StringRef &outWord)
LexOrCompleteWord & Case(llvm::StringLiteral caseStr, const T &value, bool isCompletion=true)