MLIR  20.0.0git
Parser.h
Go to the documentation of this file.
1 //===--- Parser.h - Matcher expression parser -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Simple matcher expression parser.
10 //
11 // This file contains the Parser class, which is responsible for parsing
12 // expressions in a specific format: matcherName(Arg0, Arg1, ..., ArgN). The
13 // parser can also interpret simple types, like strings.
14 //
15 // The actual processing of the matchers is handled by a Sema object that is
16 // provided to the parser.
17 //
18 // The grammar for the supported expressions is as follows:
19 // <Expression> := <StringLiteral> | <MatcherExpression>
20 // <StringLiteral> := "quoted string"
21 // <MatcherExpression> := <MatcherName>(<ArgumentList>)
22 // <MatcherName> := [a-zA-Z]+
23 // <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
24 //
25 //===----------------------------------------------------------------------===//
26 
27 #ifndef MLIR_TOOLS_MLIRQUERY_MATCHER_PARSER_H
28 #define MLIR_TOOLS_MLIRQUERY_MATCHER_PARSER_H
29 
30 #include "Diagnostics.h"
31 #include "RegistryManager.h"
32 #include "llvm/ADT/ArrayRef.h"
33 #include "llvm/ADT/StringMap.h"
34 #include "llvm/ADT/StringRef.h"
35 #include <memory>
36 #include <vector>
37 
39 
40 // Matcher expression parser.
41 class Parser {
42 public:
43  // Different possible tokens.
44  enum class TokenKind {
45  Eof,
46  NewLine,
47  OpenParen,
48  CloseParen,
49  Comma,
50  Period,
51  Literal,
52  Ident,
55  Error
56  };
57 
58  // Interface to connect the parser with the registry and more. The parser uses
59  // the Sema instance passed into parseMatcherExpression() to handle all
60  // matcher tokens.
61  class Sema {
62  public:
63  virtual ~Sema();
64 
65  // Process a matcher expression. The caller takes ownership of the Matcher
66  // object returned.
68  MatcherCtor ctor, SourceRange nameRange, llvm::StringRef functionName,
69  llvm::ArrayRef<ParserValue> args, Diagnostics *error) = 0;
70 
71  // Look up a matcher by name in the matcher name found by the parser.
72  virtual std::optional<MatcherCtor>
73  lookupMatcherCtor(llvm::StringRef matcherName) = 0;
74 
75  // Compute the list of completion types for Context.
76  virtual std::vector<ArgKind> getAcceptedCompletionTypes(
77  llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
78 
79  // Compute the list of completions that match any of acceptedTypes.
80  virtual std::vector<MatcherCompletion>
82  };
83 
84  // An implementation of the Sema interface that uses the matcher registry to
85  // process tokens.
86  class RegistrySema : public Parser::Sema {
87  public:
88  RegistrySema(const Registry &matcherRegistry)
89  : matcherRegistry(matcherRegistry) {}
90  ~RegistrySema() override;
91 
92  std::optional<MatcherCtor>
93  lookupMatcherCtor(llvm::StringRef matcherName) override;
94 
96  SourceRange NameRange,
97  StringRef functionName,
99  Diagnostics *Error) override;
100 
101  std::vector<ArgKind> getAcceptedCompletionTypes(
102  llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> context) override;
103 
104  std::vector<MatcherCompletion>
105  getMatcherCompletions(llvm::ArrayRef<ArgKind> acceptedTypes) override;
106 
107  private:
108  const Registry &matcherRegistry;
109  };
110 
111  using NamedValueMap = llvm::StringMap<VariantValue>;
112 
113  // Methods to parse a matcher expression and return a DynMatcher object,
114  // transferring ownership to the caller.
115  static std::optional<DynMatcher>
116  parseMatcherExpression(llvm::StringRef &matcherCode,
117  const Registry &matcherRegistry,
118  const NamedValueMap *namedValues, Diagnostics *error);
119  static std::optional<DynMatcher>
120  parseMatcherExpression(llvm::StringRef &matcherCode,
121  const Registry &matcherRegistry, Diagnostics *error) {
122  return parseMatcherExpression(matcherCode, matcherRegistry, nullptr, error);
123  }
124 
125  // Methods to parse any expression supported by this parser.
126  static bool parseExpression(llvm::StringRef &code,
127  const Registry &matcherRegistry,
128  const NamedValueMap *namedValues,
129  VariantValue *value, Diagnostics *error);
130 
131  static bool parseExpression(llvm::StringRef &code,
132  const Registry &matcherRegistry,
133  VariantValue *value, Diagnostics *error) {
134  return parseExpression(code, matcherRegistry, nullptr, value, error);
135  }
136 
137  // Methods to complete an expression at a given offset.
138  static std::vector<MatcherCompletion>
139  completeExpression(llvm::StringRef &code, unsigned completionOffset,
140  const Registry &matcherRegistry,
141  const NamedValueMap *namedValues);
142  static std::vector<MatcherCompletion>
143  completeExpression(llvm::StringRef &code, unsigned completionOffset,
144  const Registry &matcherRegistry) {
145  return completeExpression(code, completionOffset, matcherRegistry, nullptr);
146  }
147 
148 private:
149  class CodeTokenizer;
150  struct ScopedContextEntry;
151  struct TokenInfo;
152 
153  Parser(CodeTokenizer *tokenizer, const Registry &matcherRegistry,
154  const NamedValueMap *namedValues, Diagnostics *error);
155 
156  bool parseChainedExpression(std::string &argument);
157 
158  bool parseExpressionImpl(VariantValue *value);
159 
160  bool parseMatcherArgs(std::vector<ParserValue> &args, MatcherCtor ctor,
161  const TokenInfo &nameToken, TokenInfo &endToken);
162 
163  bool parseMatcherExpressionImpl(const TokenInfo &nameToken,
164  const TokenInfo &openToken,
165  std::optional<MatcherCtor> ctor,
166  VariantValue *value);
167 
168  bool parseIdentifierPrefixImpl(VariantValue *value);
169 
170  void addCompletion(const TokenInfo &compToken,
171  const MatcherCompletion &completion);
172  void addExpressionCompletions();
173 
174  std::vector<MatcherCompletion>
175  getNamedValueCompletions(llvm::ArrayRef<ArgKind> acceptedTypes);
176 
177  CodeTokenizer *const tokenizer;
178  std::unique_ptr<RegistrySema> sema;
179  const NamedValueMap *const namedValues;
180  Diagnostics *const error;
181 
182  using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;
183 
184  ContextStackTy contextStack;
185  std::vector<MatcherCompletion> completions;
186 };
187 
188 } // namespace mlir::query::matcher::internal
189 
190 #endif // MLIR_TOOLS_MLIRQUERY_MATCHER_PARSER_H
RegistrySema(const Registry &matcherRegistry)
Definition: Parser.h:88
std::optional< MatcherCtor > lookupMatcherCtor(llvm::StringRef matcherName) override
Definition: Parser.cpp:524
std::vector< MatcherCompletion > getMatcherCompletions(llvm::ArrayRef< ArgKind > acceptedTypes) override
Definition: Parser.cpp:540
std::vector< ArgKind > getAcceptedCompletionTypes(llvm::ArrayRef< std::pair< MatcherCtor, unsigned >> context) override
Definition: Parser.cpp:535
VariantMatcher actOnMatcherExpression(MatcherCtor Ctor, SourceRange NameRange, StringRef functionName, ArrayRef< ParserValue > Args, Diagnostics *Error) override
Definition: Parser.cpp:528
virtual std::vector< MatcherCompletion > getMatcherCompletions(llvm::ArrayRef< ArgKind > acceptedTypes)
Definition: Parser.cpp:235
virtual std::optional< MatcherCtor > lookupMatcherCtor(llvm::StringRef matcherName)=0
virtual std::vector< ArgKind > getAcceptedCompletionTypes(llvm::ArrayRef< std::pair< MatcherCtor, unsigned >> Context)
Definition: Parser.cpp:229
virtual VariantMatcher actOnMatcherExpression(MatcherCtor ctor, SourceRange nameRange, llvm::StringRef functionName, llvm::ArrayRef< ParserValue > args, Diagnostics *error)=0
static bool parseExpression(llvm::StringRef &code, const Registry &matcherRegistry, const NamedValueMap *namedValues, VariantValue *value, Diagnostics *error)
Definition: Parser.cpp:545
static std::vector< MatcherCompletion > completeExpression(llvm::StringRef &code, unsigned completionOffset, const Registry &matcherRegistry)
Definition: Parser.h:143
llvm::StringMap< VariantValue > NamedValueMap
Definition: Parser.h:111
static bool parseExpression(llvm::StringRef &code, const Registry &matcherRegistry, VariantValue *value, Diagnostics *error)
Definition: Parser.h:131
static std::optional< DynMatcher > parseMatcherExpression(llvm::StringRef &matcherCode, const Registry &matcherRegistry, Diagnostics *error)
Definition: Parser.h:120
static std::vector< MatcherCompletion > completeExpression(llvm::StringRef &code, unsigned completionOffset, const Registry &matcherRegistry, const NamedValueMap *namedValues)
Definition: Parser.cpp:564
static std::optional< DynMatcher > parseMatcherExpression(llvm::StringRef &matcherCode, const Registry &matcherRegistry, const NamedValueMap *namedValues, Diagnostics *error)
Definition: Parser.cpp:576