1f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===--- Parser.cpp - Matcher expression parser -----*- C++ -*-===// 2f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// 3f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// The LLVM Compiler Infrastructure 4f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// 5f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// This file is distributed under the University of Illinois Open Source 6f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// License. See LICENSE.TXT for details. 7f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// 8f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===----------------------------------------------------------------------===// 9f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// 10f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \file 11f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Recursive parser implementation for the matcher expression grammar. 12f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// 13f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===----------------------------------------------------------------------===// 14f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 15f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/Parser.h" 16f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/Registry.h" 17f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/Basic/CharInfo.h" 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/Optional.h" 19f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/ADT/Twine.h" 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <string> 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <vector> 22f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 23f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace clang { 24f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace ast_matchers { 25f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace dynamic { 26f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 27f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Simple structure to hold information for one token from the parser. 28f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekstruct Parser::TokenInfo { 29f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// \brief Different possible tokens. 30f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek enum TokenKind { 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_Eof, 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_OpenParen, 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_CloseParen, 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_Comma, 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_Period, 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_Literal, 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_Ident, 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_InvalidChar, 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_Error, 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TK_CodeCompletion 41f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek }; 42f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 434f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen /// \brief Some known identifiers. 444f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen static const char* const ID_Bind; 454f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen 46f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo() : Text(), Kind(TK_Eof), Range(), Value() {} 47f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 48f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek StringRef Text; 49f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenKind Kind; 50f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek SourceRange Range; 51f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek VariantValue Value; 52f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 53f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 544f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquenconst char* const Parser::TokenInfo::ID_Bind = "bind"; 554f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen 56f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Simple tokenizer for the parser. 57f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekclass Parser::CodeTokenizer { 58f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic: 59f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek explicit CodeTokenizer(StringRef MatcherCode, Diagnostics *Error) 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error), 616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CodeCompletionLocation(nullptr) { 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NextToken = getNextToken(); 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CodeTokenizer(StringRef MatcherCode, Diagnostics *Error, 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned CodeCompletionOffset) 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error), 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) { 69f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek NextToken = getNextToken(); 70f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 71f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 72f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// \brief Returns but doesn't consume the next token. 73f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const TokenInfo &peekNextToken() const { return NextToken; } 74f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 75f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// \brief Consumes and returns the next token. 76f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo consumeNextToken() { 77f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo ThisToken = NextToken; 78f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek NextToken = getNextToken(); 79f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return ThisToken; 80f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 81f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 82f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo::TokenKind nextTokenKind() const { return NextToken.Kind; } 83f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 84f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekprivate: 85f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo getNextToken() { 86f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek consumeWhitespace(); 87f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo Result; 88f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Range.Start = currentLocation(); 89f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CodeCompletionLocation && CodeCompletionLocation <= Code.data()) { 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result.Kind = TokenInfo::TK_CodeCompletion; 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result.Text = StringRef(CodeCompletionLocation, 0); 936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CodeCompletionLocation = nullptr; 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Result; 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 97f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (Code.empty()) { 98f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Kind = TokenInfo::TK_Eof; 99f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Text = ""; 100f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Result; 101f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 102f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 103f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek switch (Code[0]) { 104f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case ',': 105f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Kind = TokenInfo::TK_Comma; 106f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Text = Code.substr(0, 1); 107f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(); 108f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek break; 1094f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen case '.': 1104f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen Result.Kind = TokenInfo::TK_Period; 1114f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen Result.Text = Code.substr(0, 1); 1124f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen Code = Code.drop_front(); 1134f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen break; 114f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case '(': 115f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Kind = TokenInfo::TK_OpenParen; 116f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Text = Code.substr(0, 1); 117f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(); 118f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek break; 119f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case ')': 120f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Kind = TokenInfo::TK_CloseParen; 121f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Text = Code.substr(0, 1); 122f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(); 123f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek break; 124f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 125f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case '"': 126f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case '\'': 127f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek // Parse a string literal. 128f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek consumeStringLiteral(&Result); 129f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek break; 130f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 1317a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen case '0': case '1': case '2': case '3': case '4': 1327a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen case '5': case '6': case '7': case '8': case '9': 1337a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen // Parse an unsigned literal. 1347a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen consumeUnsignedLiteral(&Result); 1357a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen break; 1367a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 137f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek default: 138f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (isAlphanumeric(Code[0])) { 139f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek // Parse an identifier 140f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek size_t TokenLength = 1; 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (1) { 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // A code completion location in/immediately after an identifier will 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // cause the portion of the identifier before the code completion 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // location to become a code completion token. 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CodeCompletionLocation == Code.data() + TokenLength) { 1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CodeCompletionLocation = nullptr; 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result.Kind = TokenInfo::TK_CodeCompletion; 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result.Text = Code.substr(0, TokenLength); 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Code = Code.drop_front(TokenLength); 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Result; 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (TokenLength == Code.size() || !isAlphanumeric(Code[TokenLength])) 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 154f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek ++TokenLength; 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 156f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Kind = TokenInfo::TK_Ident; 157f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Text = Code.substr(0, TokenLength); 158f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(TokenLength); 159f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } else { 160f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Kind = TokenInfo::TK_InvalidChar; 161f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Text = Code.substr(0, 1); 162f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(1); 163f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 164f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek break; 165f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 166f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 167f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result.Range.End = currentLocation(); 168f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Result; 169f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 170f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 1717a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen /// \brief Consume an unsigned literal. 1727a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen void consumeUnsignedLiteral(TokenInfo *Result) { 1737a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen unsigned Length = 1; 1747a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen if (Code.size() > 1) { 1757a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen // Consume the 'x' or 'b' radix modifier, if present. 1767a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen switch (toLowercase(Code[1])) { 1777a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen case 'x': case 'b': Length = 2; 1787a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } 1797a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } 1807a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen while (Length < Code.size() && isHexDigit(Code[Length])) 1817a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen ++Length; 1827a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 1837a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Result->Text = Code.substr(0, Length); 1847a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Code = Code.drop_front(Length); 1857a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 1867a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen unsigned Value; 1877a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen if (!Result->Text.getAsInteger(0, Value)) { 1887a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Result->Kind = TokenInfo::TK_Literal; 1897a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Result->Value = Value; 1907a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } else { 1917a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen SourceRange Range; 1927a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Range.Start = Result->Range.Start; 1937a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Range.End = currentLocation(); 1948a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Range, Error->ET_ParserUnsignedError) << Result->Text; 1957a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen Result->Kind = TokenInfo::TK_Error; 1967a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } 1977a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } 1987a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 199f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// \brief Consume a string literal. 200f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// 201f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// \c Code must be positioned at the start of the literal (the opening 202f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// quote). Consumed until it finds the same closing quote character. 203f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek void consumeStringLiteral(TokenInfo *Result) { 204f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek bool InEscape = false; 205f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const char Marker = Code[0]; 206f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek for (size_t Length = 1, Size = Code.size(); Length != Size; ++Length) { 207f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (InEscape) { 208f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek InEscape = false; 209f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek continue; 210f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 211f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (Code[Length] == '\\') { 212f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek InEscape = true; 213f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek continue; 214f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 215f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (Code[Length] == Marker) { 216f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result->Kind = TokenInfo::TK_Literal; 217f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result->Text = Code.substr(0, Length + 1); 218f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result->Value = Code.substr(1, Length - 1).str(); 219f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(Length + 1); 220f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return; 221f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 222f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 223f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 224f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek StringRef ErrorText = Code; 225f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(Code.size()); 226f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek SourceRange Range; 227f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Range.Start = Result->Range.Start; 228f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Range.End = currentLocation(); 2298a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Range, Error->ET_ParserStringError) << ErrorText; 230f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Result->Kind = TokenInfo::TK_Error; 231f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 232f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 233f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek /// \brief Consume all leading whitespace from \c Code. 234f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek void consumeWhitespace() { 235f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek while (!Code.empty() && isWhitespace(Code[0])) { 236f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (Code[0] == '\n') { 237f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek ++Line; 238f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek StartOfLine = Code.drop_front(); 239f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 240f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Code = Code.drop_front(); 241f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 242f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 243f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 244f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek SourceLocation currentLocation() { 245f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek SourceLocation Location; 246f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Location.Line = Line; 247f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Location.Column = Code.data() - StartOfLine.data() + 1; 248f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Location; 249f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 250f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 251f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek StringRef Code; 252f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek StringRef StartOfLine; 253f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek unsigned Line; 254f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Diagnostics *Error; 255f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo NextToken; 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const char *CodeCompletionLocation; 257f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 258f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 259f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekParser::Sema::~Sema() {} 260f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 2616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesVariantValue Parser::Sema::getNamedValue(StringRef Name) { 2626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return VariantValue(); 2636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 2646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct Parser::ScopedContextEntry { 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Parser *P; 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ScopedContextEntry(Parser *P, MatcherCtor C) : P(P) { 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines P->ContextStack.push_back(std::make_pair(C, 0u)); 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ~ScopedContextEntry() { 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines P->ContextStack.pop_back(); 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void nextArg() { 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++P->ContextStack.back().second; 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Parse expressions that start with an identifier. 2826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// 2836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// This function can parse named values and matchers. 2846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// In case of failure it will try to determine the user's intent to give 2856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// an appropriate error message. 2866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool Parser::parseIdentifierPrefixImpl(VariantValue *Value) { 2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const TokenInfo NameToken = Tokenizer->consumeNextToken(); 2886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) { 2906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Parse as a named value. 2916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (const VariantValue NamedValue = S->getNamedValue(NameToken.Text)) { 2926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines *Value = NamedValue; 2936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 2946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If the syntax is correct and the name is not a matcher either, report 2966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // unknown named value. 2976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma || 2986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen || 2996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) && 3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !S->lookupMatcherCtor(NameToken.Text)) { 3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound) 3026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << NameToken.Text; 3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Otherwise, fallback to the matcher parser. 3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Parse as a matcher expression. 3096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return parseMatcherExpressionImpl(NameToken, Value); 3106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 3116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 312f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Parse and validate a matcher expression. 313f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \return \c true on success, in which case \c Value has the matcher parsed. 314f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// If the input is malformed, or some argument has an error, it 315f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// returns \c false. 3166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken, 3176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VariantValue *Value) { 318f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek assert(NameToken.Kind == TokenInfo::TK_Ident); 319f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const TokenInfo OpenToken = Tokenizer->consumeNextToken(); 320f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (OpenToken.Kind != TokenInfo::TK_OpenParen) { 3218a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(OpenToken.Range, Error->ET_ParserNoOpenParen) 322f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek << OpenToken.Text; 323f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return false; 324f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 325f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 3266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::Optional<MatcherCtor> Ctor = S->lookupMatcherCtor(NameToken.Text); 3276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Ctor) { 3296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Error->addError(NameToken.Range, Error->ET_RegistryMatcherNotFound) 3306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << NameToken.Text; 3316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Do not return here. We need to continue to give completion suggestions. 3326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 334f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek std::vector<ParserValue> Args; 335f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek TokenInfo EndToken; 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines { 3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr); 339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) { 341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) { 342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // End of args. 343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EndToken = Tokenizer->consumeNextToken(); 344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Args.size() > 0) { 347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We must find a , token to continue. 348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const TokenInfo CommaToken = Tokenizer->consumeNextToken(); 349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CommaToken.Kind != TokenInfo::TK_Comma) { 350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Error->addError(CommaToken.Range, Error->ET_ParserNoComma) 351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << CommaToken.Text; 352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 354f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 355f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error, 357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NameToken.Text, NameToken.Range, 358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.size() + 1); 359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ParserValue ArgValue; 360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgValue.Text = Tokenizer->peekNextToken().Text; 361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgValue.Range = Tokenizer->peekNextToken().Range; 362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!parseExpressionImpl(&ArgValue.Value)) { 363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 365f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.push_back(ArgValue); 367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SCE.nextArg(); 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 369f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 370f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 371f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (EndToken.Kind == TokenInfo::TK_Eof) { 3728a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(OpenToken.Range, Error->ET_ParserNoCloseParen); 373f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return false; 374f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 375f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 3764f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen std::string BindID; 3774f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period) { 3784f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen // Parse .bind("foo") 3794f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen Tokenizer->consumeNextToken(); // consume the period. 3804f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen const TokenInfo BindToken = Tokenizer->consumeNextToken(); 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BindToken.Kind == TokenInfo::TK_CodeCompletion) { 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addCompletion(BindToken, "bind(\"", "bind"); 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3864f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen const TokenInfo OpenToken = Tokenizer->consumeNextToken(); 3874f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen const TokenInfo IDToken = Tokenizer->consumeNextToken(); 3884f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen const TokenInfo CloseToken = Tokenizer->consumeNextToken(); 3894f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen 3904f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen // TODO: We could use different error codes for each/some to be more 3914f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen // explicit about the syntax error. 3924f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (BindToken.Kind != TokenInfo::TK_Ident || 3934f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen BindToken.Text != TokenInfo::ID_Bind) { 3948a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(BindToken.Range, Error->ET_ParserMalformedBindExpr); 3954f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen return false; 3964f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen } 3974f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (OpenToken.Kind != TokenInfo::TK_OpenParen) { 3988a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(OpenToken.Range, Error->ET_ParserMalformedBindExpr); 3994f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen return false; 4004f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen } 4014f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (IDToken.Kind != TokenInfo::TK_Literal || !IDToken.Value.isString()) { 4028a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(IDToken.Range, Error->ET_ParserMalformedBindExpr); 4034f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen return false; 4044f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen } 4054f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (CloseToken.Kind != TokenInfo::TK_CloseParen) { 4068a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(CloseToken.Range, Error->ET_ParserMalformedBindExpr); 4074f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen return false; 4084f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen } 4094f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen BindID = IDToken.Value.getString(); 4104f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen } 4114f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen 412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Ctor) 413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 415f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek // Merge the start and end infos. 4168a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error, 4178a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen NameToken.Text, NameToken.Range); 418f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek SourceRange MatcherRange = NameToken.Range; 419f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek MatcherRange.End = EndToken.Range.End; 4209d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen VariantMatcher Result = S->actOnMatcherExpression( 421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *Ctor, MatcherRange, BindID, Args, Error); 4229d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen if (Result.isNull()) return false; 423f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 424ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen *Value = Result; 425f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return true; 426f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 427f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// If the prefix of this completion matches the completion token, add it to 429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Completions minus the prefix. 430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Parser::addCompletion(const TokenInfo &CompToken, StringRef TypedText, 431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Decl) { 432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (TypedText.size() >= CompToken.Text.size() && 433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TypedText.substr(0, CompToken.Text.size()) == CompToken.Text) { 434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Completions.push_back( 435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherCompletion(TypedText.substr(CompToken.Text.size()), Decl)); 436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Parser::addExpressionCompletions() { 440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const TokenInfo CompToken = Tokenizer->consumeNextToken(); 441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(CompToken.Kind == TokenInfo::TK_CodeCompletion); 442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We cannot complete code if there is an invalid element on the context 444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // stack. 445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (ContextStackTy::iterator I = ContextStack.begin(), 446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines E = ContextStack.end(); 447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I != E; ++I) { 448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!I->first) 449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<MatcherCompletion> RegCompletions = 453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Registry::getCompletions(ContextStack); 454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (std::vector<MatcherCompletion>::iterator I = RegCompletions.begin(), 455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines E = RegCompletions.end(); 456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I != E; ++I) { 457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addCompletion(CompToken, I->TypedText, I->MatcherDecl); 458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 461f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Parse an <Expresssion> 462f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekbool Parser::parseExpressionImpl(VariantValue *Value) { 463f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek switch (Tokenizer->nextTokenKind()) { 464f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_Literal: 465f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek *Value = Tokenizer->consumeNextToken().Value; 466f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return true; 467f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 468f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_Ident: 4696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return parseIdentifierPrefixImpl(Value); 470f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case TokenInfo::TK_CodeCompletion: 472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addExpressionCompletions(); 473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 475f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_Eof: 4768a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Tokenizer->consumeNextToken().Range, 4778a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->ET_ParserNoCode); 478f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return false; 479f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 480f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_Error: 481f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek // This error was already reported by the tokenizer. 482f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return false; 483f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 484f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_OpenParen: 485f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_CloseParen: 486f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_Comma: 4874f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen case TokenInfo::TK_Period: 488f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek case TokenInfo::TK_InvalidChar: 489f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const TokenInfo Token = Tokenizer->consumeNextToken(); 4908a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Token.Range, Error->ET_ParserInvalidToken) << Token.Text; 491f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return false; 492f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 493f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 494f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek llvm_unreachable("Unknown token kind."); 495f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 496f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 497f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekParser::Parser(CodeTokenizer *Tokenizer, Sema *S, 498f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Diagnostics *Error) 499f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek : Tokenizer(Tokenizer), S(S), Error(Error) {} 500f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 5016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesParser::RegistrySema::~RegistrySema() {} 5026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Optional<MatcherCtor> 5046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesParser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) { 5056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Registry::lookupMatcherCtor(MatcherName); 5066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 5076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesVariantMatcher Parser::RegistrySema::actOnMatcherExpression( 5096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines MatcherCtor Ctor, const SourceRange &NameRange, StringRef BindID, 5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ArrayRef<ParserValue> Args, Diagnostics *Error) { 5116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BindID.empty()) { 5126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Registry::constructMatcher(Ctor, NameRange, Args, Error); 5136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 5146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args, 5156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Error); 516f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 518f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 519f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekbool Parser::parseExpression(StringRef Code, VariantValue *Value, 520f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek Diagnostics *Error) { 521f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek RegistrySema S; 522f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return parseExpression(Code, &S, Value, Error); 523f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 524f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 525f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekbool Parser::parseExpression(StringRef Code, Sema *S, 526f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek VariantValue *Value, Diagnostics *Error) { 527f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek CodeTokenizer Tokenizer(Code, Error); 5284f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (!Parser(&Tokenizer, S, Error).parseExpressionImpl(Value)) return false; 5294f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen if (Tokenizer.peekNextToken().Kind != TokenInfo::TK_Eof) { 5308a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Tokenizer.peekNextToken().Range, 5318a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->ET_ParserTrailingCode); 5324f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen return false; 5334f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen } 5344f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen return true; 535f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 536f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstd::vector<MatcherCompletion> 538651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesParser::completeExpression(StringRef Code, unsigned CompletionOffset) { 539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diagnostics Error; 540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CodeTokenizer Tokenizer(Code, &Error, CompletionOffset); 541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RegistrySema S; 542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Parser P(&Tokenizer, &S, &Error); 543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantValue Dummy; 544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines P.parseExpressionImpl(&Dummy); 545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return P.Completions; 547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 549b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenllvm::Optional<DynTypedMatcher> 550b7488d77414b000ce2506b520a6b29f845fb3950Samuel BenzaquenParser::parseMatcherExpression(StringRef Code, Diagnostics *Error) { 551f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek RegistrySema S; 552f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return parseMatcherExpression(Code, &S, Error); 553f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 554f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 555b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenllvm::Optional<DynTypedMatcher> 556b7488d77414b000ce2506b520a6b29f845fb3950Samuel BenzaquenParser::parseMatcherExpression(StringRef Code, Parser::Sema *S, 557b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen Diagnostics *Error) { 558f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek VariantValue Value; 559f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (!parseExpression(Code, S, &Value, Error)) 560b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return llvm::Optional<DynTypedMatcher>(); 5619d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen if (!Value.isMatcher()) { 5628a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(SourceRange(), Error->ET_ParserNotAMatcher); 563b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return llvm::Optional<DynTypedMatcher>(); 564f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 565b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen llvm::Optional<DynTypedMatcher> Result = 566b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen Value.getMatcher().getSingleMatcher(); 567b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen if (!Result.hasValue()) { 5688a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(SourceRange(), Error->ET_ParserOverloadedType) 569ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen << Value.getTypeAsString(); 570ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen } 571b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return Result; 572f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 573f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 574f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace dynamic 575f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace ast_matchers 576f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace clang 577