ast_matchers {
72: Code(MatcherCode), StartOfLine(MatcherCode), Error(Error) {
73NextToken = getNextToken();
77 unsignedCodeCompletionOffset)
78: Code(MatcherCode), StartOfLine(MatcherCode), Error(Error),
79CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) {
80NextToken = getNextToken();
89NextToken = getNextToken();
95NextToken = getNextToken();
112 Result.Range.Start = currentLocation();
114 if(CodeCompletionLocation && CodeCompletionLocation <= Code.data()) {
116 Result.Text = StringRef(CodeCompletionLocation, 0);
117CodeCompletionLocation =
nullptr;
129Code = Code.drop_until([](
char c) {
return c==
'\n'; });
130 returngetNextToken();
133 Result.Text = Code.substr(0, 1);
134Code = Code.drop_front();
138 Result.Text = Code.substr(0, 1);
139Code = Code.drop_front();
143StartOfLine = Code.drop_front();
145 Result.Text = Code.substr(0, 1);
146Code = Code.drop_front();
150 Result.Text = Code.substr(0, 1);
151Code = Code.drop_front();
155 Result.Text = Code.substr(0, 1);
156Code = Code.drop_front();
162consumeStringLiteral(&
Result);
165 case '0':
case '1':
case '2':
case '3':
case '4':
166 case '5':
case '6':
case '7':
case '8':
case '9':
168consumeNumberLiteral(&
Result);
174 size_tTokenLength = 1;
179 if(CodeCompletionLocation == Code.data() + TokenLength) {
180CodeCompletionLocation =
nullptr;
182 Result.Text = Code.substr(0, TokenLength);
183Code = Code.drop_front(TokenLength);
186 if(TokenLength == Code.size() || !
isAlphanumeric(Code[TokenLength]))
190 if(TokenLength == 4 && Code.starts_with(
"true")) {
193}
else if(TokenLength == 5 && Code.starts_with(
"false")) {
198 Result.Text = Code.substr(0, TokenLength);
200Code = Code.drop_front(TokenLength);
203 Result.Text = Code.substr(0, 1);
204Code = Code.drop_front(1);
209 Result.Range.End = currentLocation();
214 voidconsumeNumberLiteral(TokenInfo *
Result) {
215 boolisFloatingLiteral =
false;
217 if(Code.size() > 1) {
220 case 'x':
case 'b': Length = 2;
223 while(Length < Code.size() &&
isHexDigit(Code[Length]))
227 while(Length < Code.size()) {
228 char c= Code[Length];
230isFloatingLiteral =
true;
237 Result->Text = Code.substr(0, Length);
238Code = Code.drop_front(Length);
240 if(isFloatingLiteral) {
244 doubledoubleValue = strtod(
Text.c_str(), &end);
245 if(*end == 0 && errno == 0) {
247 Result->Value = doubleValue;
261 Range.End = currentLocation();
270 voidconsumeStringLiteral(TokenInfo *
Result) {
271 boolInEscape =
false;
272 const charMarker = Code[0];
273 for(
size_tLength = 1, Size = Code.size(); Length != Size; ++Length) {
278 if(Code[Length] ==
'\\') {
282 if(Code[Length] == Marker) {
284 Result->Text = Code.substr(0, Length + 1);
285 Result->Value = Code.substr(1, Length - 1);
286Code = Code.drop_front(Length + 1);
291StringRef ErrorText = Code;
292Code = Code.drop_front(Code.size());
295 Range.End = currentLocation();
301 voidconsumeWhitespace() {
303Code = Code.ltrim(
" \t\v\f\r");
306SourceLocation currentLocation() {
307SourceLocation Location;
308Location.Line = Line;
309Location.Column = Code.data() - StartOfLine.data() + 1;
314StringRef StartOfLine;
318 const char*CodeCompletionLocation =
nullptr;
328std::vector<MatcherCompletion>
337 P->ContextStack.push_back(std::make_pair(C, 0u));
341 P->ContextStack.pop_back();
345++
P->ContextStack.back().second;
360NamedValues ? NamedValues->lookup(NameToken.Text)
364*
Value= NamedValue;
372addCompletion(ChainCallToken, MatcherCompletion(
"bind(\"",
"bind", 1));
379Error->
addError(ChainCallToken.Range,
386NameToken.Text, NameToken.Range);
388Error->
addError(ChainCallToken.Range,
392 if(!parseBindID(BindID))
395assert(NamedValue.isMatcher());
396std::optional<DynTypedMatcher>
Result=
397NamedValue.getMatcher().getSingleMatcher();
399std::optional<DynTypedMatcher> Bound =
Result->tryBind(BindID);
442 returnparseMatcherExpressionImpl(NameToken, OpenToken, Ctor,
Value);
445boolParser::parseBindID(std::string &BindID) {
465BindID = IDToken.Value.getString();
469boolParser::parseMatcherBuilder(
MatcherCtorCtor,
constTokenInfo &NameToken,
470 constTokenInfo &OpenToken,
471VariantValue *
Value) {
472std::vector<ParserValue> Args;
478ScopedContextEntry SCE(
this, Ctor);
497NameToken.Text, NameToken.Range,
499ParserValue ArgValue;
503addExpressionCompletions();
515ArgValue.Text = NodeMatcherToken.Text;
516ArgValue.Range = NodeMatcherToken.Range;
518std::optional<MatcherCtor> MappedMatcher =
521 if(!MappedMatcher) {
522Error->
addError(NodeMatcherToken.Range,
524<< NodeMatcherToken.Text;
531Error->
addError(NodeMatcherToken.Range,
533<< NodeMatcherToken.Text;
540Args.push_back(ArgValue);
551internal::MatcherDescriptorPtr BuiltCtor =
554 if(!BuiltCtor.get()) {
565addCompletion(ChainCallToken, MatcherCompletion(
"bind(\"",
"bind", 1));
566addCompletion(ChainCallToken, MatcherCompletion(
"with(",
"with", 1));
572Error->
addError(ChainCallToken.Range,
577 if(!parseBindID(BindID))
580NameToken.Text, NameToken.Range);
581SourceRange MatcherRange = NameToken.Range;
582MatcherRange.End = ChainCallToken.Range.End;
584BuiltCtor.get(), MatcherRange, BindID, {}, Error);
596: Tokenizer->peekNextToken().
Text;
605 returnparseMatcherExpressionImpl(NameToken, WithOpenToken,
606BuiltCtor.get(),
Value);
611NameToken.Text, NameToken.Range);
612SourceRange MatcherRange = NameToken.Range;
613MatcherRange.End = EndToken.Range.End;
615BuiltCtor.get(), MatcherRange, BindID, {}, Error);
627boolParser::parseMatcherExpressionImpl(
constTokenInfo &NameToken,
628 constTokenInfo &OpenToken,
629std::optional<MatcherCtor> Ctor,
630VariantValue *
Value) {
638 returnparseMatcherBuilder(*Ctor, NameToken, OpenToken,
Value);
640std::vector<ParserValue> Args;
646ScopedContextEntry SCE(
this, Ctor.value_or(
nullptr));
665NameToken.Text, NameToken.Range,
667ParserValue ArgValue;
671 if(!parseExpressionImpl(&ArgValue.Value)) {
676Args.push_back(ArgValue);
691addCompletion(ChainCallToken, MatcherCompletion(
"bind(\"",
"bind", 1));
696Error->
addError(ChainCallToken.Range,
703NameToken.Text, NameToken.Range);
705Error->
addError(ChainCallToken.Range,
710Error->
addError(ChainCallToken.Range,
714 if(!parseBindID(BindID))
723NameToken.Text, NameToken.Range);
724SourceRange MatcherRange = NameToken.Range;
725MatcherRange.End = EndToken.Range.End;
727*Ctor, MatcherRange, BindID, Args, Error);
728 if(
Result.isNull())
return false;
736voidParser::addCompletion(
constTokenInfo &CompToken,
737 constMatcherCompletion& Completion) {
738 if(StringRef(Completion.TypedText).starts_with(CompToken.Text) &&
739Completion.Specificity > 0) {
740Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()),
741Completion.MatcherDecl, Completion.Specificity);
745std::vector<MatcherCompletion> Parser::getNamedValueCompletions(
746ArrayRef<ArgKind> AcceptedTypes) {
747 if(!NamedValues)
returnstd::vector<MatcherCompletion>();
748std::vector<MatcherCompletion>
Result;
749 for(
const auto&Entry : *NamedValues) {
750 unsignedSpecificity;
751 if(Entry.getValue().isConvertibleTo(AcceptedTypes, &Specificity)) {
753(Entry.getValue().getTypeAsString() +
" "+ Entry.getKey()).str();
754 Result.emplace_back(Entry.getKey(),
Decl, Specificity);
760voidParser::addExpressionCompletions() {
766 for(ContextStackTy::iterator I = ContextStack.begin(),
767 E= ContextStack.end();
775addCompletion(CompToken, Completion);
778 for(
const auto&Completion : getNamedValueCompletions(AcceptedTypes)) {
779addCompletion(CompToken, Completion);
784boolParser::parseExpressionImpl(VariantValue *
Value) {
791 returnparseIdentifierPrefixImpl(
Value);
794addExpressionCompletions();
817llvm_unreachable(
"Unknown token kind.");
822Parser::Parser(CodeTokenizer *Tokenizer,
Sema*S,
825NamedValues(NamedValues), Error(Error) {}
827Parser::RegistrySema::~RegistrySema() =
default;
829std::optional<MatcherCtor>
830Parser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
831 returnRegistry::lookupMatcherCtor(MatcherName);
837 if(BindID.empty()) {
838 returnRegistry::constructMatcher(Ctor, NameRange, Args, Error);
840 returnRegistry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
845std::vector<ArgKind> Parser::RegistrySema::getAcceptedCompletionTypes(
846 ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
847 returnRegistry::getAcceptedCompletionTypes(Context);
850std::vector<MatcherCompletion> Parser::RegistrySema::getMatcherCompletions(
852 returnRegistry::getMatcherCompletions(AcceptedTypes);
855boolParser::RegistrySema::isBuilderMatcher(
MatcherCtorCtor)
const{
856 returnRegistry::isBuilderMatcher(Ctor);
860 returnRegistry::nodeMatcherType(Ctor);
867 returnRegistry::buildMatcherCtor(Ctor, NameRange, Args, Error);
870boolParser::parseExpression(StringRef &Code,
Sema*S,
874 if(!
Parser(&Tokenizer, S, NamedValues, Error).parseExpressionImpl(
Value))
876 autoNT = Tokenizer.peekNextToken();
877 if(NT.Kind != TokenInfo::TK_Eof && NT.Kind != TokenInfo::TK_NewLine) {
878Error->addError(Tokenizer.peekNextToken().Range,
879Error->ET_ParserTrailingCode);
885std::vector<MatcherCompletion>
886Parser::completeExpression(StringRef &Code,
unsignedCompletionOffset,
Sema*S,
890 Parser P(&Tokenizer, S, NamedValues, &Error);
892 P.parseExpressionImpl(&Dummy);
895llvm::sort(
P.Completions,
897if (A.Specificity != B.Specificity)
898return A.Specificity > B.Specificity;
899return A.TypedText < B.TypedText;
902 return P.Completions;
905std::optional<DynTypedMatcher>
906Parser::parseMatcherExpression(StringRef &Code,
Sema*S,
910 if(!parseExpression(Code, S, NamedValues, &
Value, Error))
912 if(!
Value.isMatcher()) {
913Error->addError(
SourceRange(), Error->ET_ParserNotAMatcher);
916std::optional<DynTypedMatcher>
Result=
Value.getMatcher().getSingleMatcher();
918Error->addError(
SourceRange(), Error->ET_ParserOverloadedType)
919<<
Value.getTypeAsString();
Simple matcher expression parser.
Diagnostics class to manage error messages.
Registry of all known matchers.
__device__ __2f16 float c
Sema - This implements semantic analysis and AST building for C.
Helper class to manage error messages.
ArgStream addError(SourceRange Range, ErrorType Error)
Add an error to the diagnostics.
@ ET_ParserMalformedBindExpr
@ ET_RegistryValueNotFound
@ ET_ParserFailedToBuildMatcher
@ ET_RegistryMatcherNotFound
@ ET_RegistryNonNodeMatcher
@ ET_ParserMalformedChainedExpr
@ ET_RegistryMatcherNoWithSupport
Simple tokenizer for the parser.
TokenInfo consumeNextTokenIgnoreNewlines()
CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error, unsigned CodeCompletionOffset)
TokenInfo::TokenKind nextTokenKind() const
CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error)
TokenInfo consumeNextToken()
Consumes and returns the next token.
const TokenInfo & peekNextToken() const
Returns but doesn't consume the next token.
Interface to connect the parser with the registry and more.
virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor, SourceRange NameRange, StringRef BindID, ArrayRef< ParserValue > Args, Diagnostics *Error)=0
Process a matcher expression.
virtual internal::MatcherDescriptorPtr buildMatcherCtor(MatcherCtor, SourceRange NameRange, ArrayRef< ParserValue > Args, Diagnostics *Error) const =0
virtual std::optional< MatcherCtor > lookupMatcherCtor(StringRef MatcherName)=0
Look up a matcher by name.
virtual std::vector< ArgKind > getAcceptedCompletionTypes(llvm::ArrayRef< std::pair< MatcherCtor, unsigned > > Context)
Compute the list of completion types for Context.
virtual bool isBuilderMatcher(MatcherCtor) const =0
virtual std::vector< MatcherCompletion > getMatcherCompletions(llvm::ArrayRef< ArgKind > AcceptedTypes)
Compute the list of completions that match any of AcceptedTypes.
virtual ASTNodeKind nodeMatcherType(MatcherCtor) const =0
Matcher expression parser.
llvm::StringMap< VariantValue > NamedValueMap
A variant matcher object.
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher)
Clones the provided matcher.
A smart (owning) pointer for MatcherDescriptor.
Matcher descriptor interface.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
static llvm::ManagedStatic< Parser::RegistrySema > DefaultRegistrySema
const internal::MatcherDescriptor * MatcherCtor
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY char toLowercase(char c)
Converts the given ASCII character to its lowercase equivalent.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Result
The result type of a method or function.
LLVM_READONLY bool isHexDigit(unsigned char c)
Return true if this character is an ASCII hex digit: [0-9a-fA-F].
ScopedContextEntry(Parser *P, MatcherCtor C)
Simple structure to hold information for one token from the parser.
TokenKind
Different possible tokens.
static const char *const ID_Bind
Some known identifiers.
static const char *const ID_With
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4