1 //===- Parser.h - MLIR Base Parser Class ------------------------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef MLIR_LIB_ASMPARSER_PARSER_H
10 #define MLIR_LIB_ASMPARSER_PARSER_H
12 #include "ParserState.h"
13 #include "mlir/IR/Builders.h"
14 #include "mlir/IR/OpImplementation.h"
19 //===----------------------------------------------------------------------===//
21 //===----------------------------------------------------------------------===//
23 /// This class implement support for parsing global entities like attributes and
24 /// types. It is intended to be subclassed by specialized subparsers that
28 using Delimiter
= OpAsmParser::Delimiter
;
32 Parser(ParserState
&state
)
33 : builder(state
.config
.getContext()), state(state
) {}
35 // Helper methods to get stuff from the parser-global state.
36 ParserState
&getState() const { return state
; }
37 MLIRContext
*getContext() const { return state
.config
.getContext(); }
38 const llvm::SourceMgr
&getSourceMgr() { return state
.lex
.getSourceMgr(); }
40 /// Parse a comma-separated list of elements up until the specified end token.
42 parseCommaSeparatedListUntil(Token::Kind rightToken
,
43 function_ref
<ParseResult()> parseElement
,
44 bool allowEmptyList
= true);
46 /// Parse a list of comma-separated items with an optional delimiter. If a
47 /// delimiter is provided, then an empty list is allowed. If not, then at
48 /// least one element will be parsed.
50 parseCommaSeparatedList(Delimiter delimiter
,
51 function_ref
<ParseResult()> parseElementFn
,
52 StringRef contextMessage
= StringRef());
54 /// Parse a comma separated list of elements that must have at least one entry
57 parseCommaSeparatedList(function_ref
<ParseResult()> parseElementFn
) {
58 return parseCommaSeparatedList(Delimiter::None
, parseElementFn
);
61 /// Parse the body of a dialect symbol, which starts and ends with <>'s, and
62 /// may be recursive. Return with the 'body' StringRef encompassing the entire
63 /// body. `isCodeCompletion` is set to true if the body contained a code
64 /// completion location, in which case the body is only populated up to the
66 ParseResult
parseDialectSymbolBody(StringRef
&body
, bool &isCodeCompletion
);
67 ParseResult
parseDialectSymbolBody(StringRef
&body
) {
68 bool isCodeCompletion
= false;
69 return parseDialectSymbolBody(body
, isCodeCompletion
);
72 // We have two forms of parsing methods - those that return a non-null
73 // pointer on success, and those that return a ParseResult to indicate whether
74 // they returned a failure. The second class fills in by-reference arguments
75 // as the results of their action.
77 //===--------------------------------------------------------------------===//
79 //===--------------------------------------------------------------------===//
81 /// Emit an error and return failure.
82 InFlightDiagnostic
emitError(const Twine
&message
= {});
83 InFlightDiagnostic
emitError(SMLoc loc
, const Twine
&message
= {});
85 /// Emit an error about a "wrong token". If the current token is at the
86 /// start of a source line, this will apply heuristics to back up and report
87 /// the error at the end of the previous line, which is where the expected
88 /// token is supposed to be.
89 InFlightDiagnostic
emitWrongTokenError(const Twine
&message
= {});
91 /// Encode the specified source location information into an attribute for
92 /// attachment to the IR.
93 Location
getEncodedSourceLocation(SMLoc loc
) {
94 return state
.lex
.getEncodedSourceLocation(loc
);
97 //===--------------------------------------------------------------------===//
99 //===--------------------------------------------------------------------===//
101 /// Return the current token the parser is inspecting.
102 const Token
&getToken() const { return state
.curToken
; }
103 StringRef
getTokenSpelling() const { return state
.curToken
.getSpelling(); }
105 /// Return the last parsed token.
106 const Token
&getLastToken() const { return state
.lastToken
; }
108 /// If the current token has the specified kind, consume it and return true.
109 /// If not, return false.
110 bool consumeIf(Token::Kind kind
) {
111 if (state
.curToken
.isNot(kind
))
117 /// Advance the current lexer onto the next token.
118 void consumeToken() {
119 assert(state
.curToken
.isNot(Token::eof
, Token::error
) &&
120 "shouldn't advance past EOF or errors");
121 state
.lastToken
= state
.curToken
;
122 state
.curToken
= state
.lex
.lexToken();
125 /// Advance the current lexer onto the next token, asserting what the expected
126 /// current token is. This is preferred to the above method because it leads
127 /// to more self-documenting code with better checking.
128 void consumeToken(Token::Kind kind
) {
129 assert(state
.curToken
.is(kind
) && "consumed an unexpected token");
133 /// Reset the parser to the given lexer position.
134 void resetToken(const char *tokPos
) {
135 state
.lex
.resetPointer(tokPos
);
136 state
.lastToken
= state
.curToken
;
137 state
.curToken
= state
.lex
.lexToken();
140 /// Consume the specified token if present and return success. On failure,
141 /// output a diagnostic and return failure.
142 ParseResult
parseToken(Token::Kind expectedToken
, const Twine
&message
);
144 /// Parse an optional integer value from the stream.
145 OptionalParseResult
parseOptionalInteger(APInt
&result
);
147 /// Parse a floating point value from an integer literal token.
148 ParseResult
parseFloatFromIntegerLiteral(std::optional
<APFloat
> &result
,
149 const Token
&tok
, bool isNegative
,
150 const llvm::fltSemantics
&semantics
,
151 size_t typeSizeInBits
);
153 /// Returns true if the current token corresponds to a keyword.
154 bool isCurrentTokenAKeyword() const {
155 return getToken().isAny(Token::bare_identifier
, Token::inttype
) ||
156 getToken().isKeyword();
159 /// Parse a keyword, if present, into 'keyword'.
160 ParseResult
parseOptionalKeyword(StringRef
*keyword
);
162 //===--------------------------------------------------------------------===//
164 //===--------------------------------------------------------------------===//
166 /// Parse a handle to a dialect resource within the assembly format.
167 FailureOr
<AsmDialectResourceHandle
>
168 parseResourceHandle(const OpAsmDialectInterface
*dialect
, StringRef
&name
);
169 FailureOr
<AsmDialectResourceHandle
> parseResourceHandle(Dialect
*dialect
);
171 //===--------------------------------------------------------------------===//
173 //===--------------------------------------------------------------------===//
175 /// Invoke the `getChecked` method of the given Attribute or Type class, using
176 /// the provided location to emit errors in the case of failure. Note that
177 /// unlike `OpBuilder::getType`, this method does not implicitly insert a
178 /// context parameter.
179 template <typename T
, typename
... ParamsT
>
180 T
getChecked(SMLoc loc
, ParamsT
&&...params
) {
181 return T::getChecked([&] { return emitError(loc
); },
182 std::forward
<ParamsT
>(params
)...);
185 ParseResult
parseFunctionResultTypes(SmallVectorImpl
<Type
> &elements
);
186 ParseResult
parseTypeListNoParens(SmallVectorImpl
<Type
> &elements
);
187 ParseResult
parseTypeListParens(SmallVectorImpl
<Type
> &elements
);
189 /// Optionally parse a type.
190 OptionalParseResult
parseOptionalType(Type
&type
);
192 /// Parse an arbitrary type.
195 /// Parse a complex type.
196 Type
parseComplexType();
198 /// Parse an extended type.
199 Type
parseExtendedType();
201 /// Parse a function type.
202 Type
parseFunctionType();
204 /// Parse a memref type.
205 Type
parseMemRefType();
207 /// Parse a non function type.
208 Type
parseNonFunctionType();
210 /// Parse a tensor type.
211 Type
parseTensorType();
213 /// Parse a tuple type.
214 Type
parseTupleType();
216 /// Parse a vector type.
217 VectorType
parseVectorType();
218 ParseResult
parseVectorDimensionList(SmallVectorImpl
<int64_t> &dimensions
,
219 SmallVectorImpl
<bool> &scalableDims
);
220 ParseResult
parseDimensionListRanked(SmallVectorImpl
<int64_t> &dimensions
,
221 bool allowDynamic
= true,
222 bool withTrailingX
= true);
223 ParseResult
parseIntegerInDimensionList(int64_t &value
);
224 ParseResult
parseXInDimensionList();
226 //===--------------------------------------------------------------------===//
228 //===--------------------------------------------------------------------===//
230 /// Parse an arbitrary attribute with an optional type.
231 Attribute
parseAttribute(Type type
= {});
233 /// Parse an optional attribute with the provided type.
234 OptionalParseResult
parseOptionalAttribute(Attribute
&attribute
,
236 OptionalParseResult
parseOptionalAttribute(ArrayAttr
&attribute
, Type type
);
237 OptionalParseResult
parseOptionalAttribute(StringAttr
&attribute
, Type type
);
238 OptionalParseResult
parseOptionalAttribute(SymbolRefAttr
&result
, Type type
);
240 /// Parse an optional attribute that is demarcated by a specific token.
241 template <typename AttributeT
>
242 OptionalParseResult
parseOptionalAttributeWithToken(Token::Kind kind
,
245 if (getToken().isNot(kind
))
248 if (Attribute parsedAttr
= parseAttribute(type
)) {
249 attr
= cast
<AttributeT
>(parsedAttr
);
255 /// Parse an attribute dictionary.
256 ParseResult
parseAttributeDict(NamedAttrList
&attributes
);
258 /// Parse a distinct attribute.
259 Attribute
parseDistinctAttr(Type type
);
261 /// Parse an extended attribute.
262 Attribute
parseExtendedAttr(Type type
);
264 /// Parse a float attribute.
265 Attribute
parseFloatAttr(Type type
, bool isNegative
);
267 /// Parse a decimal or a hexadecimal literal, which can be either an integer
268 /// or a float attribute.
269 Attribute
parseDecOrHexAttr(Type type
, bool isNegative
);
271 /// Parse a dense elements attribute.
272 Attribute
parseDenseElementsAttr(Type attrType
);
273 ShapedType
parseElementsLiteralType(Type type
);
275 /// Parse a dense resource elements attribute.
276 Attribute
parseDenseResourceElementsAttr(Type attrType
);
278 /// Parse a DenseArrayAttr.
279 Attribute
parseDenseArrayAttr(Type type
);
281 /// Parse a sparse elements attribute.
282 Attribute
parseSparseElementsAttr(Type attrType
);
284 /// Parse a strided layout attribute.
285 Attribute
parseStridedLayoutAttr();
287 //===--------------------------------------------------------------------===//
289 //===--------------------------------------------------------------------===//
291 /// Parse a raw location instance.
292 ParseResult
parseLocationInstance(LocationAttr
&loc
);
294 /// Parse a callsite location instance.
295 ParseResult
parseCallSiteLocation(LocationAttr
&loc
);
297 /// Parse a fused location instance.
298 ParseResult
parseFusedLocation(LocationAttr
&loc
);
300 /// Parse a name or FileLineCol location instance.
301 ParseResult
parseNameOrFileLineColLocation(LocationAttr
&loc
);
303 //===--------------------------------------------------------------------===//
305 //===--------------------------------------------------------------------===//
307 /// Parse a reference to either an affine map, expr, or an integer set.
308 ParseResult
parseAffineMapOrIntegerSetReference(AffineMap
&map
,
310 ParseResult
parseAffineMapReference(AffineMap
&map
);
312 parseAffineExprReference(ArrayRef
<std::pair
<StringRef
, AffineExpr
>> symbolSet
,
314 ParseResult
parseIntegerSetReference(IntegerSet
&set
);
316 /// Parse an AffineMap where the dim and symbol identifiers are SSA ids.
318 parseAffineMapOfSSAIds(AffineMap
&map
,
319 function_ref
<ParseResult(bool)> parseElement
,
320 Delimiter delimiter
);
322 /// Parse an AffineExpr where dim and symbol identifiers are SSA ids.
324 parseAffineExprOfSSAIds(AffineExpr
&expr
,
325 function_ref
<ParseResult(bool)> parseElement
);
327 //===--------------------------------------------------------------------===//
329 //===--------------------------------------------------------------------===//
331 /// The set of various code completion methods. Every completion method
332 /// returns `failure` to signal that parsing should abort after any desired
333 /// completions have been enqueued. Note that `failure` is does not mean
334 /// completion failed, it's just a signal to the parser to stop.
336 ParseResult
codeCompleteDialectName();
337 ParseResult
codeCompleteOperationName(StringRef dialectName
);
338 ParseResult
codeCompleteDialectOrElidedOpName(SMLoc loc
);
339 ParseResult
codeCompleteStringDialectOrOperationName(StringRef name
);
340 ParseResult
codeCompleteExpectedTokens(ArrayRef
<StringRef
> tokens
);
341 ParseResult
codeCompleteOptionalTokens(ArrayRef
<StringRef
> tokens
);
343 Attribute
codeCompleteAttribute();
344 Type
codeCompleteType();
346 codeCompleteDialectSymbol(const llvm::StringMap
<Attribute
> &aliases
);
347 Type
codeCompleteDialectSymbol(const llvm::StringMap
<Type
> &aliases
);
350 /// The Parser is subclassed and reinstantiated. Do not add additional
351 /// non-trivial state here, add it to the ParserState class.
354 } // namespace detail
357 #endif // MLIR_LIB_ASMPARSER_PARSER_H