clang: lib/Tooling/Transformer/Parsing.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/Errc.h"
20#include "llvm/Support/Error.h"
21#include
22#include
23#include
24#include
25
26using namespace clang;
27using namespace transformer;
28
29
30
31
32
33
34
35namespace {
37
38template <typename... Ts> using RangeSelectorOp = RangeSelector (*)(Ts...);
39
40struct ParseState {
41
42 StringRef Input;
43
44
45 StringRef OriginalInput;
46};
47
48
49
50template struct ParseProgress {
51 ParseState State;
52
54};
55
57template using ParseFunction = ExpectedProgress (*)(ParseState);
58
59class ParseError : public llvm::ErrorInfo {
60public:
61
62 static char ID;
63
64 ParseError(size_t Pos, std::string ErrorMsg, std::string InputExcerpt)
65 : Pos(Pos), ErrorMsg(std::move(ErrorMsg)),
66 Excerpt(std::move(InputExcerpt)) {}
67
68 void log(llvm::raw_ostream &OS) const override {
69 OS << "parse error at position (" << Pos << "): " << ErrorMsg
70 << ": " + Excerpt;
71 }
72
73 std::error_code convertToErrorCode() const override {
74 return llvm::inconvertibleErrorCode();
75 }
76
77
78 size_t Pos;
79 std::string ErrorMsg;
80
81 std::string Excerpt;
82};
83
84char ParseError::ID;
85}
86
87static const llvm::StringMap<RangeSelectorOpstd::string> &
89 static const llvm::StringMap<RangeSelectorOpstd::string> M = {
90 {"name", name},
91 {"node", node},
98 return M;
99}
100
101static const llvm::StringMap<RangeSelectorOp> &
103 static const llvm::StringMap<RangeSelectorOp> M = {
105 return M;
106}
107
108static const llvm::StringMap<RangeSelectorOp<std::string, std::string>> &
110 static const llvm::StringMap<RangeSelectorOp<std::string, std::string>> M = {
112 return M;
113}
114
115static const llvm::StringMap<RangeSelectorOp<RangeSelector, RangeSelector>> &
117 static const llvm::StringMap<RangeSelectorOp<RangeSelector, RangeSelector>>
119 return M;
120}
121
122template
123std::optional findOptional(const llvm::StringMap &Map,
124 llvm::StringRef Key) {
125 auto it = Map.find(Key);
126 if (it == Map.end())
127 return std::nullopt;
128 return it->second;
129}
130
131template
133 ResultType Result) {
134 return ParseProgress{State, std::move(Result)};
135}
136
137static llvm::Error makeParseError(const ParseState &S, std::string ErrorMsg) {
138 size_t Pos = S.OriginalInput.size() - S.Input.size();
139 return llvm::make_error(Pos, std::move(ErrorMsg),
140 S.OriginalInput.substr(Pos, 20).str());
141}
142
143
144static ParseState advance(ParseState S, size_t N) {
145 S.Input = S.Input.drop_front(N);
146 return S;
147}
148
151}
152
153
154
155static ExpectedProgressstd::nullopt\_t parseChar(char c, ParseState State) {
157 if (State.Input.empty() || State.Input.front() != c)
159 ("expected char not found: " + llvm::Twine(c)).str());
161}
162
163
164static ExpectedProgressstd::string parseId(ParseState State) {
166 auto Id = State.Input.take_while(
168 if (Id.empty())
169 return makeParseError(State, "failed to parse name");
171}
172
173
174
175static ExpectedProgressstd::string parseStringId(ParseState State) {
177 if (State.Input.empty())
178 return makeParseError(State, "unexpected end of input");
179 if (!State.Input.consume_front("\""))
181 State,
182 "expecting string, but encountered other character or end of input");
183
184 StringRef Id = State.Input.take_until([](char c) { return c == '"'; });
185 if (State.Input.size() == Id.size())
187
189}
190
191
192
193template
194ExpectedProgress parseSingle(ParseFunction ParseElement,
195 RangeSelectorOp Op,
196 ParseState State) {
198 if ()
199 return P.takeError();
200
201 auto E = ParseElement(P->State);
202 if ()
203 return E.takeError();
204
206 if ()
207 return P.takeError();
208
210}
211
212
213
214template
215ExpectedProgress parsePair(ParseFunction ParseElement,
216 RangeSelectorOp<T, T> Op,
217 ParseState State) {
219 if ()
220 return P.takeError();
221
222 auto Left = ParseElement(P->State);
223 if (!Left)
224 return Left.takeError();
225
227 if ()
228 return P.takeError();
229
230 auto Right = ParseElement(P->State);
231 if (!Right)
232 return Right.takeError();
233
235 if ()
236 return P.takeError();
237
239 Op(std::move(Left->Value), std::move(Right->Value)));
240}
241
242
243
244
245static ExpectedProgress
248 if ()
249 return Id.takeError();
250
251 std::string OpName = std::move(Id->Value);
254
257
260
263
264 return makeParseError(State, "unknown selector name: " + OpName);
265}
266
268 ParseState State = {Input, Input};
270 if (!Result)
271 return Result.takeError();
272 State = Result->State;
273
275 if (State.Input.empty())
276 return Result->Value;
277 return makeParseError(State, "unexpected input after selector");
278}
static ExpectedProgress< std::string > parseStringId(ParseState State)
static ExpectedProgress< std::nullopt_t > parseChar(char c, ParseState State)
ParseProgress< ResultType > makeParseProgress(ParseState State, ResultType Result)
static StringRef consumeWhitespace(StringRef S)
ExpectedProgress< RangeSelector > parseSingle(ParseFunction< T > ParseElement, RangeSelectorOp< T > Op, ParseState State)
ExpectedProgress< RangeSelector > parsePair(ParseFunction< T > ParseElement, RangeSelectorOp< T, T > Op, ParseState State)
std::optional< Element > findOptional(const llvm::StringMap< Element > &Map, llvm::StringRef Key)
static llvm::Error makeParseError(const ParseState &S, std::string ErrorMsg)
static const llvm::StringMap< RangeSelectorOp< RangeSelector > > & getUnaryRangeSelectors()
static ExpectedProgress< RangeSelector > parseRangeSelectorImpl(ParseState State)
static ExpectedProgress< std::string > parseId(ParseState State)
static ParseState advance(ParseState S, size_t N)
static const llvm::StringMap< RangeSelectorOp< RangeSelector, RangeSelector > > & getBinaryRangeSelectors()
static const llvm::StringMap< RangeSelectorOp< std::string, std::string > > & getBinaryStringSelectors()
static const llvm::StringMap< RangeSelectorOp< std::string > > & getUnaryStringSelectors()
Defines parsing functions for Transformer types.
Defines a combinator library supporting the definition of selectors, which select source ranges based...
Defines the clang::SourceLocation class and associated facilities.
__device__ __2f16 float c
RangeSelector initListElements(std::string ID)
RangeSelector enclose(RangeSelector Begin, RangeSelector End)
Selects from the start of Begin and to the end of End.
RangeSelector member(std::string ID)
Given a MemberExpr, selects the member token.
RangeSelector between(RangeSelector R1, RangeSelector R2)
Selects the range between R1 and `R2.
RangeSelector elseBranch(std::string ID)
Given an \IfStmt (bound to ID), selects the range of the else branch, starting from the else keyword.
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...
MatchConsumer< CharSourceRange > RangeSelector
RangeSelector encloseNodes(std::string BeginID, std::string EndID)
Convenience version of range where end-points are bound nodes.
RangeSelector after(RangeSelector Selector)
Selects the point immediately following Selector.
RangeSelector callArgs(std::string ID)
RangeSelector before(RangeSelector Selector)
Selects the (empty) range [B,B) when Selector selects the range [B,E).
llvm::Expected< RangeSelector > parseRangeSelector(llvm::StringRef Input)
Parses a string representation of a RangeSelector.
RangeSelector statement(std::string ID)
Selects a node, including trailing semicolon (always).
RangeSelector expansion(RangeSelector S)
Selects the range from which S was expanded (possibly along with other source), if S is an expansion,...
RangeSelector statements(std::string ID)
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READNONE bool isASCII(char c)
Returns true if a byte is an ASCII character.
LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)
LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t',...