bolt/deps/llvm-18.1.8/mlir/lib/Query/Matcher/Parser.h
2025-02-14 19:21:04 +01:00

188 lines
6.7 KiB
C++

//===--- Parser.h - Matcher expression parser -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Simple matcher expression parser.
//
// This file contains the Parser class, which is responsible for parsing
// expressions in a specific format: matcherName(Arg0, Arg1, ..., ArgN). The
// parser can also interpret simple types, like strings.
//
// The actual processing of the matchers is handled by a Sema object that is
// provided to the parser.
//
// The grammar for the supported expressions is as follows:
// <Expression> := <StringLiteral> | <MatcherExpression>
// <StringLiteral> := "quoted string"
// <MatcherExpression> := <MatcherName>(<ArgumentList>)
// <MatcherName> := [a-zA-Z]+
// <ArgumentList> := <Expression> | <Expression>,<ArgumentList>
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_TOOLS_MLIRQUERY_MATCHER_PARSER_H
#define MLIR_TOOLS_MLIRQUERY_MATCHER_PARSER_H
#include "Diagnostics.h"
#include "RegistryManager.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
#include <vector>
namespace mlir::query::matcher::internal {
// Matcher expression parser.
class Parser {
public:
// Different possible tokens.
enum class TokenKind {
Eof,
NewLine,
OpenParen,
CloseParen,
Comma,
Period,
Literal,
Ident,
InvalidChar,
CodeCompletion,
Error
};
// Interface to connect the parser with the registry and more. The parser uses
// the Sema instance passed into parseMatcherExpression() to handle all
// matcher tokens.
class Sema {
public:
virtual ~Sema();
// Process a matcher expression. The caller takes ownership of the Matcher
// object returned.
virtual VariantMatcher
actOnMatcherExpression(MatcherCtor ctor, SourceRange nameRange,
llvm::ArrayRef<ParserValue> args,
Diagnostics *error) = 0;
// Look up a matcher by name in the matcher name found by the parser.
virtual std::optional<MatcherCtor>
lookupMatcherCtor(llvm::StringRef matcherName) = 0;
// Compute the list of completion types for Context.
virtual std::vector<ArgKind> getAcceptedCompletionTypes(
llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
// Compute the list of completions that match any of acceptedTypes.
virtual std::vector<MatcherCompletion>
getMatcherCompletions(llvm::ArrayRef<ArgKind> acceptedTypes);
};
// An implementation of the Sema interface that uses the matcher registry to
// process tokens.
class RegistrySema : public Parser::Sema {
public:
RegistrySema(const Registry &matcherRegistry)
: matcherRegistry(matcherRegistry) {}
~RegistrySema() override;
std::optional<MatcherCtor>
lookupMatcherCtor(llvm::StringRef matcherName) override;
VariantMatcher actOnMatcherExpression(MatcherCtor ctor,
SourceRange nameRange,
llvm::ArrayRef<ParserValue> args,
Diagnostics *error) override;
std::vector<ArgKind> getAcceptedCompletionTypes(
llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> context) override;
std::vector<MatcherCompletion>
getMatcherCompletions(llvm::ArrayRef<ArgKind> acceptedTypes) override;
private:
const Registry &matcherRegistry;
};
using NamedValueMap = llvm::StringMap<VariantValue>;
// Methods to parse a matcher expression and return a DynMatcher object,
// transferring ownership to the caller.
static std::optional<DynMatcher>
parseMatcherExpression(llvm::StringRef &matcherCode,
const Registry &matcherRegistry,
const NamedValueMap *namedValues, Diagnostics *error);
static std::optional<DynMatcher>
parseMatcherExpression(llvm::StringRef &matcherCode,
const Registry &matcherRegistry, Diagnostics *error) {
return parseMatcherExpression(matcherCode, matcherRegistry, nullptr, error);
}
// Methods to parse any expression supported by this parser.
static bool parseExpression(llvm::StringRef &code,
const Registry &matcherRegistry,
const NamedValueMap *namedValues,
VariantValue *value, Diagnostics *error);
static bool parseExpression(llvm::StringRef &code,
const Registry &matcherRegistry,
VariantValue *value, Diagnostics *error) {
return parseExpression(code, matcherRegistry, nullptr, value, error);
}
// Methods to complete an expression at a given offset.
static std::vector<MatcherCompletion>
completeExpression(llvm::StringRef &code, unsigned completionOffset,
const Registry &matcherRegistry,
const NamedValueMap *namedValues);
static std::vector<MatcherCompletion>
completeExpression(llvm::StringRef &code, unsigned completionOffset,
const Registry &matcherRegistry) {
return completeExpression(code, completionOffset, matcherRegistry, nullptr);
}
private:
class CodeTokenizer;
struct ScopedContextEntry;
struct TokenInfo;
Parser(CodeTokenizer *tokenizer, const Registry &matcherRegistry,
const NamedValueMap *namedValues, Diagnostics *error);
bool parseExpressionImpl(VariantValue *value);
bool parseMatcherArgs(std::vector<ParserValue> &args, MatcherCtor ctor,
const TokenInfo &nameToken, TokenInfo &endToken);
bool parseMatcherExpressionImpl(const TokenInfo &nameToken,
const TokenInfo &openToken,
std::optional<MatcherCtor> ctor,
VariantValue *value);
bool parseIdentifierPrefixImpl(VariantValue *value);
void addCompletion(const TokenInfo &compToken,
const MatcherCompletion &completion);
void addExpressionCompletions();
std::vector<MatcherCompletion>
getNamedValueCompletions(llvm::ArrayRef<ArgKind> acceptedTypes);
CodeTokenizer *const tokenizer;
std::unique_ptr<RegistrySema> sema;
const NamedValueMap *const namedValues;
Diagnostics *const error;
using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;
ContextStackTy contextStack;
std::vector<MatcherCompletion> completions;
};
} // namespace mlir::query::matcher::internal
#endif // MLIR_TOOLS_MLIRQUERY_MATCHER_PARSER_H