1//===--- Parser.h - Matcher expression parser -----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Simple matcher expression parser.
12///
13/// The parser understands matcher expressions of the form:
14///   MatcherName(Arg0, Arg1, ..., ArgN)
15/// as well as simple types like strings.
16/// The parser does not know how to process the matchers. It delegates this task
17/// to a Sema object received as an argument.
18///
19/// \code
20/// Grammar for the expressions supported:
21/// <Expression>        := <Literal> | <MatcherExpression>
22/// <Literal>           := <StringLiteral> | <Unsigned>
23/// <StringLiteral>     := "quoted string"
24/// <Unsigned>          := [0-9]+
25/// <MatcherExpression> := <MatcherName>(<ArgumentList>) |
26///                        <MatcherName>(<ArgumentList>).bind(<StringLiteral>)
27/// <MatcherName>       := [a-zA-Z]+
28/// <ArgumentList>      := <Expression> | <Expression>,<ArgumentList>
29/// \endcode
30///
31//===----------------------------------------------------------------------===//
32
33#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
34#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
35
36#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
37#include "clang/ASTMatchers/Dynamic/VariantValue.h"
38#include "clang/Basic/LLVM.h"
39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/StringRef.h"
42
43namespace clang {
44namespace ast_matchers {
45namespace dynamic {
46
47/// \brief Matcher expression parser.
48class Parser {
49public:
50  /// \brief Interface to connect the parser with the registry and more.
51  ///
52  /// The parser uses the Sema instance passed into
53  /// parseMatcherExpression() to handle all matcher tokens. The simplest
54  /// processor implementation would simply call into the registry to create
55  /// the matchers.
56  /// However, a more complex processor might decide to intercept the matcher
57  /// creation and do some extra work. For example, it could apply some
58  /// transformation to the matcher by adding some id() nodes, or could detect
59  /// specific matcher nodes for more efficient lookup.
60  class Sema {
61  public:
62    virtual ~Sema();
63
64    /// \brief Process a matcher expression.
65    ///
66    /// All the arguments passed here have already been processed.
67    ///
68    /// \param MatcherName The matcher name found by the parser.
69    ///
70    /// \param NameRange The location of the name in the matcher source.
71    ///   Useful for error reporting.
72    ///
73    /// \param BindID The ID to use to bind the matcher, or a null \c StringRef
74    ///   if no ID is specified.
75    ///
76    /// \param Args The argument list for the matcher.
77    ///
78    /// \return The matcher objects constructed by the processor, or a null
79    ///   matcher if an error occurred. In that case, \c Error will contain a
80    ///   description of the error.
81    virtual VariantMatcher actOnMatcherExpression(StringRef MatcherName,
82                                                  const SourceRange &NameRange,
83                                                  StringRef BindID,
84                                                  ArrayRef<ParserValue> Args,
85                                                  Diagnostics *Error) = 0;
86  };
87
88  /// \brief Parse a matcher expression, creating matchers from the registry.
89  ///
90  /// This overload creates matchers calling directly into the registry. If the
91  /// caller needs more control over how the matchers are created, then it can
92  /// use the overload below that takes a Sema.
93  ///
94  /// \param MatcherCode The matcher expression to parse.
95  ///
96  /// \return The matcher object constructed, or an empty Optional if an error
97  ///   occurred.
98  ///   In that case, \c Error will contain a description of the error.
99  ///   The caller takes ownership of the DynTypedMatcher object returned.
100  static llvm::Optional<DynTypedMatcher>
101  parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error);
102
103  /// \brief Parse a matcher expression.
104  ///
105  /// \param MatcherCode The matcher expression to parse.
106  ///
107  /// \param S The Sema instance that will help the parser
108  ///   construct the matchers.
109  /// \return The matcher object constructed by the processor, or an empty
110  ///   Optional if an error occurred. In that case, \c Error will contain a
111  ///   description of the error.
112  ///   The caller takes ownership of the DynTypedMatcher object returned.
113  static llvm::Optional<DynTypedMatcher>
114  parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error);
115
116  /// \brief Parse an expression, creating matchers from the registry.
117  ///
118  /// Parses any expression supported by this parser. In general, the
119  /// \c parseMatcherExpression function is a better approach to get a matcher
120  /// object.
121  static bool parseExpression(StringRef Code, VariantValue *Value,
122                              Diagnostics *Error);
123
124  /// \brief Parse an expression.
125  ///
126  /// Parses any expression supported by this parser. In general, the
127  /// \c parseMatcherExpression function is a better approach to get a matcher
128  /// object.
129  static bool parseExpression(StringRef Code, Sema *S,
130                              VariantValue *Value, Diagnostics *Error);
131
132private:
133  class CodeTokenizer;
134  struct TokenInfo;
135
136  Parser(CodeTokenizer *Tokenizer, Sema *S,
137         Diagnostics *Error);
138
139  bool parseExpressionImpl(VariantValue *Value);
140  bool parseMatcherExpressionImpl(VariantValue *Value);
141
142  CodeTokenizer *const Tokenizer;
143  Sema *const S;
144  Diagnostics *const Error;
145};
146
147}  // namespace dynamic
148}  // namespace ast_matchers
149}  // namespace clang
150
151#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
152