brintos

brintos / llvm-project-archived public Read only

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