Lines Matching +full:- +full:- +full:token
1 //===- AttributeParser.cpp - MLIR Attribute Parser Implementation ---------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
33 /// attribute-value ::= `unit`
34 /// | bool-literal
35 /// | integer-literal (`:` (index-type | integer-type))?
36 /// | float-literal (`:` float-type)?
37 /// | string-literal (`:` type)?
39 /// | `[` `:` (integer-type | float-type) tensor-literal `]`
40 /// | `[` (attribute-value (`,` attribute-value)*)? `]`
41 /// | `{` (attribute-entry (`,` attribute-entry)*)? `}`
42 /// | symbol-ref-id (`::` symbol-ref-id)*
43 /// | `dense` `<` tensor-literal `>` `:`
44 /// (tensor-type | vector-type)
45 /// | `sparse` `<` attribute-value `,` attribute-value `>`
46 /// `:` (tensor-type | vector-type)
47 /// | `strided` `<` `[` comma-separated-int-or-question `]`
48 /// (`,` `offset` `:` integer-literal)? `>`
49 /// | distinct-attribute
50 /// | extended-attribute
55 case Token::kw_affine_map: {
56 consumeToken(Token::kw_affine_map);
59 if (parseToken(Token::less, "expected '<' in affine map") ||
61 parseToken(Token::greater, "expected '>' in affine map"))
65 case Token::kw_affine_set: {
66 consumeToken(Token::kw_affine_set);
69 if (parseToken(Token::less, "expected '<' in integer set") ||
71 parseToken(Token::greater, "expected '>' in integer set"))
77 case Token::l_square: {
78 consumeToken(Token::l_square);
80 auto parseElt = [&]() -> ParseResult {
85 if (parseCommaSeparatedListUntil(Token::r_square, parseElt))
91 case Token::kw_false:
92 consumeToken(Token::kw_false);
94 case Token::kw_true:
95 consumeToken(Token::kw_true);
99 case Token::kw_dense:
103 case Token::kw_dense_resource:
107 case Token::kw_array:
111 case Token::l_brace: {
119 case Token::hash_identifier:
123 case Token::floatliteral:
125 case Token::integer:
127 case Token::minus: {
128 consumeToken(Token::minus);
129 if (getToken().is(Token::integer))
131 if (getToken().is(Token::floatliteral))
140 case Token::kw_loc: {
141 consumeToken(Token::kw_loc);
144 if (parseToken(Token::l_paren, "expected '(' in inline location") ||
146 parseToken(Token::r_paren, "expected ')' in inline location"))
152 case Token::kw_sparse:
156 case Token::kw_strided:
160 case Token::kw_distinct:
164 case Token::string: {
166 consumeToken(Token::string);
168 if (!type && consumeIf(Token::colon) && !(type = parseType()))
176 case Token::at_identifier: {
183 // Parse the top-level reference.
185 consumeToken(Token::at_identifier);
189 while (getToken().is(Token::colon)) {
192 consumeToken(Token::colon);
193 if (!consumeIf(Token::colon)) {
194 if (getToken().isNot(Token::eof, Token::error)) {
202 if (getToken().isNot(Token::at_identifier)) {
213 consumeToken(Token::at_identifier);
221 state.asmState->addUses(symbolRefAttr, referenceLocations);
226 case Token::kw_unit:
227 consumeToken(Token::kw_unit);
231 case Token::code_complete:
232 if (getToken().isCodeCompletionFor(Token::hash_identifier))
251 case Token::at_identifier:
252 case Token::floatliteral:
253 case Token::integer:
254 case Token::hash_identifier:
255 case Token::kw_affine_map:
256 case Token::kw_affine_set:
257 case Token::kw_dense:
258 case Token::kw_dense_resource:
259 case Token::kw_false:
260 case Token::kw_loc:
261 case Token::kw_sparse:
262 case Token::kw_true:
263 case Token::kw_unit:
264 case Token::l_brace:
265 case Token::l_square:
266 case Token::minus:
267 case Token::string:
282 return parseOptionalAttributeWithToken(Token::l_square, attribute, type);
286 return parseOptionalAttributeWithToken(Token::string, attribute, type);
290 return parseOptionalAttributeWithToken(Token::at_identifier, result, type);
295 /// attribute-dict ::= `{` `}`
296 /// | `{` attribute-entry (`,` attribute-entry)* `}`
297 /// attribute-entry ::= (bare-id | string-literal) `=` attribute-value
301 auto parseElt = [&]() -> ParseResult {
304 if (getToken().is(Token::string))
306 else if (getToken().isAny(Token::bare_identifier, Token::inttype) ||
312 if (nameId->empty())
317 << nameId->getValue() << "' in dictionary attribute";
321 auto splitName = nameId->strref().split('.');
323 getContext()->getOrLoadDialect(splitName.first);
326 if (!consumeIf(Token::equal)) {
348 consumeToken(Token::floatliteral);
351 if (!consumeIf(Token::colon))
359 return FloatAttr::get(type, isNegative ? -*val : *val);
381 if (result.countl_zero() < result.getBitWidth() - width)
389 // assert, so short-cut validation here.
411 Token tok = getToken();
415 consumeToken(Token::integer);
418 if (!consumeIf(Token::colon))
449 //===----------------------------------------------------------------------===//
451 //===----------------------------------------------------------------------===//
455 static ParseResult parseElementAttrHexValues(Parser &parser, Token tok,
467 /// either a single element (e.g, 5) or a multi-dimensional list of elements
500 /// parseElement(1) -> Success, 1
501 /// parseElement([1]) -> Failure
505 /// parsed sub-tensors in dims. For example:
506 /// parseList([1, 2, 3]) -> Success, [3]
507 /// parseList([[1, 2], [3, 4]]) -> Success, [2, 2]
508 /// parseList([[1, 2], 3]) -> Failure
509 /// parseList([[1, [2, 3]], [4, [5]]]) -> Failure
520 /// Storage used when parsing elements, this is a pair of <is_negated, token>.
521 std::vector<std::pair<bool, Token>> storage;
524 std::optional<Token> hexStorage;
532 if (allowHex && p.getToken().is(Token::string)) {
534 p.consumeToken(Token::string);
538 if (p.getToken().is(Token::l_square))
616 const Token &token = signAndToken.second;
617 auto tokenLoc = token.getLoc();
625 if (token.is(Token::floatliteral)) {
627 << "expected integer elements, but parsed floating-point";
630 assert(token.isAny(Token::integer, Token::kw_true, Token::kw_false) &&
631 "unexpected token type");
632 if (token.isAny(Token::kw_true, Token::kw_false)) {
637 APInt apInt(1, token.is(Token::kw_true), /*isSigned=*/false);
644 buildAttributeAPInt(eltTy, isNegative, token.getSpelling());
659 const Token &token = signAndToken.second;
661 if (failed(p.parseFloatFromLiteral(result, token, isNegative,
673 auto stringValue = hexStorage->getStringValue();
695 << "expected floating-point, integer, or complex element type, got "
713 // Convert endianess in big-endian(BE) machines. `rawData` is
714 // little-endian(LE) because HEX in raw data of dense element attribute
730 case Token::kw_true:
731 case Token::kw_false:
732 case Token::floatliteral:
733 case Token::integer:
738 // Parse a signed integer or a negative floating-point element.
739 case Token::minus:
740 p.consumeToken(Token::minus);
741 if (!p.getToken().isAny(Token::floatliteral, Token::integer))
747 case Token::string:
753 case Token::l_paren:
754 p.consumeToken(Token::l_paren);
756 p.parseToken(Token::comma, "expected ',' between complex elements") ||
758 p.parseToken(Token::r_paren, "expected ')' after complex elements"))
770 /// parsed sub-tensors in dims. For example:
771 /// parseList([1, 2, 3]) -> Success, [3]
772 /// parseList([[1, 2], [3, 4]]) -> Success, [2, 2]
773 /// parseList([[1, 2], 3]) -> Failure
774 /// parseList([[1, [2, 3]], [4, [5]]]) -> Failure
777 const SmallVectorImpl<int64_t> &newDims) -> ParseResult {
787 auto parseOneElement = [&]() -> ParseResult {
789 if (p.getToken().getKind() == Token::l_square) {
812 //===----------------------------------------------------------------------===//
814 //===----------------------------------------------------------------------===//
858 bool isNegative = p.consumeIf(Token::minus);
863 if (p.getToken().isAny(Token::kw_true, Token::kw_false)) {
866 value = APInt(/*numBits=*/8, p.getToken().is(Token::kw_true),
869 } else if (p.consumeIf(Token::integer)) {
881 bool isNegative = p.consumeIf(Token::minus);
882 Token token = p.getToken();
885 p.parseFloatFromLiteral(fromIntLit, token, isNegative,
889 append(fromIntLit->bitcastToAPInt());
895 consumeToken(Token::kw_array);
896 if (parseToken(Token::less, "expected '<' after 'array'"))
918 if (consumeIf(Token::greater))
921 if (parseToken(Token::colon, "expected ':' after dense array type"))
934 if (parseToken(Token::greater, "expected '>' to close an array attribute"))
942 consumeToken(Token::kw_dense);
943 if (parseToken(Token::less, "expected '<' after 'dense'"))
948 if (!consumeIf(Token::greater)) {
950 parseToken(Token::greater, "expected '>'"))
966 consumeToken(Token::kw_dense_resource);
967 if (parseToken(Token::less, "expected '<' after 'dense_resource'"))
972 parseResourceHandle(getContext()->getLoadedDialect<BuiltinDialect>());
973 if (failed(rawHandle) || parseToken(Token::greater, "expected '>'"))
984 if (parseToken(Token::colon, "expected ':'") || !(attrType = parseType()))
999 /// elements-literal-type ::= vector-type | ranked-tensor-type
1005 if (parseToken(Token::colon, "expected ':'"))
1026 consumeToken(Token::kw_sparse);
1027 if (parseToken(Token::less, "Expected '<' after 'sparse'"))
1031 // represented by a 2-dimensional shape where the second dimension is the rank
1034 if (consumeIf(Token::greater)) {
1056 if (parseToken(Token::comma, "expected ','"))
1065 if (parseToken(Token::greater, "expected '>'"))
1074 // 2-dimensional shape where the second dimension is the rank of the type.
1101 // Callback for error emissing at the keyword token location.
1105 consumeToken(Token::kw_strided);
1106 if (failed(parseToken(Token::less, "expected '<' after 'strided'")) ||
1107 failed(parseToken(Token::l_square, "expected '['")))
1110 // Parses either an integer token or a question mark token. Reports an error
1111 // and returns std::nullopt if the current token is neither. The integer token
1113 auto parseStrideOrOffset = [&]() -> std::optional<int64_t> {
1114 if (consumeIf(Token::question))
1119 emitError(loc, "expected a 64-bit signed integer or '?'");
1123 bool negative = consumeIf(Token::minus);
1125 if (getToken().is(Token::integer)) {
1133 result = -result;
1143 if (!getToken().is(Token::r_square)) {
1149 } while (consumeIf(Token::comma));
1152 if (failed(parseToken(Token::r_square, "expected ']'")))
1156 if (consumeIf(Token::greater)) {
1163 if (failed(parseToken(Token::comma, "expected ','")) ||
1164 failed(parseToken(Token::kw_offset, "expected 'offset' after comma")) ||
1165 failed(parseToken(Token::colon, "expected ':' after 'offset'")))
1169 if (!offset || failed(parseToken(Token::greater, "expected '>'")))
1180 /// distinct-attribute ::= `distinct`
1181 /// `[` integer-literal `]<` attribute-value `>`
1185 consumeToken(Token::kw_distinct);
1186 if (parseToken(Token::l_square, "expected '[' after 'distinct'"))
1190 Token token = getToken();
1191 if (parseToken(Token::integer, "expected distinct ID"))
1193 std::optional<uint64_t> value = token.getUInt64IntegerValue();
1195 emitError("expected an unsigned 64-bit integer");
1200 if (parseToken(Token::r_square, "expected ']' to close distinct ID") ||
1201 parseToken(Token::less, "expected '<' after distinct ID"))
1205 if (getToken().is(Token::greater)) {
1215 if (parseToken(Token::greater, "expected '>' to close distinct attribute"))
1228 } else if (it->getSecond().getReferencedAttr() != referencedAttr) {
1230 << it->getSecond().getReferencedAttr();
1234 return it->getSecond();