@felixtensor/tree-sitter-mlir 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/grammar.js CHANGED
@@ -2,16 +2,20 @@
2
2
  // @ts-check
3
3
 
4
4
  export default grammar({
5
- name: 'mlir',
6
- extras: $ => [/\s/, $.comment],
7
- conflicts: $ => [
5
+ name: "mlir",
6
+ extras: ($) => [/[\s\x00]/, $.comment],
7
+ conflicts: ($) => [
8
8
  [$._static_dim_list, $._static_dim_list],
9
9
  [$.dictionary_attribute, $.region],
10
10
  [$.custom_op_name, $.attribute_entry],
11
11
  [$.type_alias, $.dialect_namespace],
12
12
  [$.dialect_namespace, $.attribute_alias],
13
13
  [$.pretty_dialect_item],
14
- [$.array_literal, $._custom_body_element],
14
+ [$.array_literal, $._custom_body_element_base],
15
+ [$._custom_body_element_base, $.tensor_type],
16
+ [$._custom_body_element_base, $._custom_body_arrow],
17
+ [$._generic_custom_operation_with_location_attr_dict, $.custom_op_name],
18
+ [$._custom_body_dict_key, $.attribute_entry],
15
19
  [$._value_use_list, $._value_use_and_type],
16
20
  [$._type_list_no_parens, $._type_or_func_type],
17
21
  [$._type_list_parens, $._multi_dim_affine_expr_parens],
@@ -32,12 +36,18 @@ export default grammar({
32
36
  rules: {
33
37
  // =========================================================================
34
38
  // Top level production:
35
- // (operation | attribute-alias-def | type-alias-def)
39
+ // (operation | attribute-alias-def | type-alias-def)*
36
40
  // =========================================================================
37
- toplevel: $ => seq($._toplevel, repeat($._toplevel)),
38
- _toplevel: $ => choice($.operation, $.attribute_alias_def, $.type_alias_def,
39
- $.external_resources),
40
- external_resources: $ => seq('{-#', repeat($._pretty_dialect_item_contents), '#-}'),
41
+ toplevel: ($) => repeat($._toplevel),
42
+ _toplevel: ($) =>
43
+ choice(
44
+ $.operation,
45
+ $.attribute_alias_def,
46
+ $.type_alias_def,
47
+ $.external_resources,
48
+ ),
49
+ external_resources: ($) =>
50
+ seq("{-#", repeat($._pretty_dialect_item_contents), "#-}"),
41
51
 
42
52
  // =========================================================================
43
53
  // Common syntax (lang-ref)
@@ -47,42 +57,95 @@ export default grammar({
47
57
  // float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
48
58
  // string-literal ::= `"` [^"\n\f\v\r]* `"`
49
59
  // =========================================================================
50
- _digit: $ => /[0-9]/,
51
- integer_literal: $ => choice($._decimal_literal, $._hexadecimal_literal),
52
- _decimal_literal: $ => token(seq(optional(/[-+]/), repeat1(/[0-9]/))),
53
- _hexadecimal_literal: $ => token(seq('0x', repeat1(/[0-9a-fA-F]/))),
54
- float_literal: $ => token(seq(
55
- optional(/[-+]/), repeat1(/[0-9]/), '.', repeat(/[0-9]/),
56
- optional(seq(/[eE]/, optional(/[-+]/), repeat1(/[0-9]/))))),
57
- string_literal: $ => seq(
58
- '"',
59
- repeat(choice(/[^\\"\n\f\v\r]+/, $.escape_sequence, $.invalid_escape)),
60
- '"'
61
- ),
62
- escape_sequence: $ => token(seq('\\', choice(/[nt"\\]/, /[0-9a-fA-F]{2}/))),
63
- invalid_escape: $ => token(seq('\\', /[^\n\f\v\r]/)),
64
- bool_literal: $ => token(choice('true', 'false')),
65
- unit_literal: $ => token('unit'),
66
- uninitialized_literal: $ => token('uninitialized'),
67
- complex_literal: $ => seq('(', choice($.integer_literal, $.float_literal, $.bool_literal), ',',
68
- choice($.integer_literal, $.float_literal, $.bool_literal), ')'),
69
- tensor_literal: $ => seq(token(choice('dense', 'sparse')), '<',
70
- optional(seq(
71
- optional(seq($.type, ':')),
72
- seq($._tensor_literal_element, repeat(seq(',', $._tensor_literal_element)))
73
- )), '>'),
74
- _tensor_literal_element: $ => choice($.nested_idx_list, $._primitive_element),
75
- array_literal: $ => seq(token('array'), '<', $.type, optional(seq(':', $._idx_list)), '>'),
76
- _literal: $ => choice($.integer_literal, $.float_literal, $.string_literal, $.bool_literal,
77
- $.tensor_literal, $.array_literal, $.unit_literal, $.uninitialized_literal),
78
-
79
- nested_idx_list: $ => seq('[', optional(choice($.nested_idx_list, $._idx_list)),
80
- repeat(seq(',', $.nested_idx_list)), ']'),
81
- _idx_list: $ => prec.right(seq($._primitive_element,
82
- repeat(seq(',', $._primitive_element)))),
83
- _primitive_element: $ => seq($._primitive_idx_literal, optional(seq(':', $.type))),
84
- _primitive_idx_literal: $ => choice($.integer_literal, $.float_literal,
85
- $.bool_literal, $.complex_literal, $.string_literal),
60
+ _digit: ($) => /[0-9]/,
61
+ integer_literal: ($) => choice($._decimal_literal, $._hexadecimal_literal),
62
+ _decimal_literal: ($) => token(seq(optional(/[-+]/), repeat1(/[0-9]/))),
63
+ _unsigned_decimal_literal: ($) => token(repeat1(/[0-9]/)),
64
+ _unsigned_integer_literal: ($) =>
65
+ choice($._unsigned_decimal_literal, $._hexadecimal_literal),
66
+ _hexadecimal_literal: ($) => token(seq("0x", repeat1(/[0-9a-fA-F]/))),
67
+ float_literal: ($) =>
68
+ token(
69
+ seq(
70
+ optional(/[-+]/),
71
+ repeat1(/[0-9]/),
72
+ ".",
73
+ repeat(/[0-9]/),
74
+ optional(seq(/[eE]/, optional(/[-+]/), repeat1(/[0-9]/))),
75
+ ),
76
+ ),
77
+ string_literal: ($) =>
78
+ seq(
79
+ '"',
80
+ repeat(choice(/[^\\"\n\f\v\r]+/, $.escape_sequence, $.invalid_escape)),
81
+ '"',
82
+ ),
83
+ escape_sequence: ($) =>
84
+ token(seq("\\", choice(/[nt"\\]/, /[0-9a-fA-F]{2}/))),
85
+ invalid_escape: ($) => token(seq("\\", /[^\n\f\v\r]/)),
86
+ bool_literal: ($) => token(choice("true", "false")),
87
+ unit_literal: ($) => token("unit"),
88
+ uninitialized_literal: ($) => token("uninitialized"),
89
+ complex_literal: ($) =>
90
+ seq(
91
+ "(",
92
+ choice($.integer_literal, $.float_literal, $.bool_literal),
93
+ ",",
94
+ choice($.integer_literal, $.float_literal, $.bool_literal),
95
+ ")",
96
+ ),
97
+ tensor_literal: ($) =>
98
+ seq(
99
+ choice($._dense_keyword, $._sparse_keyword),
100
+ "<",
101
+ optional(
102
+ seq(
103
+ optional(seq($.type, ":")),
104
+ seq(
105
+ $._tensor_literal_element,
106
+ repeat(seq(",", $._tensor_literal_element)),
107
+ ),
108
+ ),
109
+ ),
110
+ ">",
111
+ ),
112
+ _tensor_literal_element: ($) =>
113
+ choice($.nested_idx_list, $._primitive_element),
114
+ array_literal: ($) =>
115
+ seq(token("array"), "<", $.type, optional(seq(":", $._idx_list)), ">"),
116
+ _literal: ($) =>
117
+ choice(
118
+ $.integer_literal,
119
+ $.float_literal,
120
+ $.string_literal,
121
+ $.bool_literal,
122
+ $.tensor_literal,
123
+ $.array_literal,
124
+ $.unit_literal,
125
+ $.uninitialized_literal,
126
+ ),
127
+
128
+ nested_idx_list: ($) =>
129
+ seq(
130
+ "[",
131
+ optional(choice($.nested_idx_list, $._idx_list)),
132
+ repeat(seq(",", $.nested_idx_list)),
133
+ "]",
134
+ ),
135
+ _idx_list: ($) =>
136
+ prec.right(
137
+ seq($._primitive_element, repeat(seq(",", $._primitive_element))),
138
+ ),
139
+ _primitive_element: ($) =>
140
+ seq($._primitive_idx_literal, optional(seq(":", $.type))),
141
+ _primitive_idx_literal: ($) =>
142
+ choice(
143
+ $.integer_literal,
144
+ $.float_literal,
145
+ $.bool_literal,
146
+ $.complex_literal,
147
+ $.string_literal,
148
+ ),
86
149
 
87
150
  // =========================================================================
88
151
  // Identifiers
@@ -91,16 +154,28 @@ export default grammar({
91
154
  // suffix-id ::= (digit+ | ((letter|id-punct) (letter|id-punct|digit)*))
92
155
  // symbol-ref-id ::= `@` (suffix-id | string-literal) (`::` symbol-ref-id)?
93
156
  // =========================================================================
94
- bare_id: $ => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.]/))),
95
- _alias_or_dialect_id: $ => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/))),
96
- bare_id_list: $ => seq($.bare_id, repeat(seq(',', $.bare_id))),
97
- value_use: $ => seq('%', $._suffix_id),
98
- _suffix_id: $ => token(seq(choice(repeat1(/[0-9]/),
99
- seq(/[a-zA-Z_$.-]/, repeat(/[a-zA-Z0-9_$.-]/))),
100
- optional(seq(choice(':', '#'), repeat1(/[0-9]/))))),
101
- symbol_ref_id: $ => seq('@', choice($._suffix_id, $.string_literal),
102
- optional(seq('::', $.symbol_ref_id))),
103
- _value_use_list: $ => seq($.value_use, repeat(seq(',', $.value_use))),
157
+ bare_id: ($) => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.]/))),
158
+ _alias_or_dialect_id: ($) =>
159
+ token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/))),
160
+ bare_id_list: ($) => seq($.bare_id, repeat(seq(",", $.bare_id))),
161
+ value_use: ($) => seq("%", $._suffix_id),
162
+ _suffix_id: ($) =>
163
+ token(
164
+ seq(
165
+ choice(
166
+ repeat1(/[0-9]/),
167
+ seq(/[a-zA-Z_$.-]/, repeat(/[a-zA-Z0-9_$.-]/)),
168
+ ),
169
+ optional(seq(choice(":", "#"), repeat1(/[0-9]/))),
170
+ ),
171
+ ),
172
+ symbol_ref_id: ($) =>
173
+ seq(
174
+ "@",
175
+ choice($._suffix_id, $.string_literal),
176
+ optional(seq("::", $.symbol_ref_id)),
177
+ ),
178
+ _value_use_list: ($) => seq($.value_use, repeat(seq(",", $.value_use))),
104
179
 
105
180
  // =========================================================================
106
181
  // Operations
@@ -111,58 +186,86 @@ export default grammar({
111
186
  // dictionary-attribute? `:` function-type
112
187
  // custom-operation ::= bare-id custom-operation-format
113
188
  // =========================================================================
114
- operation: $ => seq(
115
- field('lhs', optional($._op_result_list)),
116
- field('rhs', choice($.generic_operation, $.custom_operation)),
117
- field('location', optional($.trailing_location))),
118
-
119
- generic_operation: $ =>
120
- seq($.string_literal, $._value_use_list_parens, optional($._successor_list),
121
- optional($.properties), optional($._region_list), optional($.attribute),
122
- ':', $.function_type),
123
-
124
- _op_result_list: $ => seq($.op_result, repeat(seq(',', $.op_result)), '='),
125
- op_result: $ => seq($.value_use, optional(seq(':', $.integer_literal))),
126
- _successor_list: $ => seq('[', $.successor, repeat(seq(',', $.successor)), ']'),
127
- successor: $ => prec.right(seq($.caret_id, optional($._value_arg_list))),
128
- _region_list: $ => seq('(', $.region, repeat(seq(',', $.region)), ')'),
129
- properties: $ => seq('<{', optional($.attribute_entry),
130
- repeat(seq(',', $.attribute_entry)), '}>'),
131
- dictionary_attribute: $ => seq('{', optional($.attribute_entry),
132
- repeat(seq(',', $.attribute_entry)), '}'),
133
- trailing_location: $ => seq(token('loc'), '(', $.location, ')'),
189
+ operation: ($) =>
190
+ seq(
191
+ field("lhs", optional($._op_result_list)),
192
+ field("rhs", choice($.generic_operation, $.custom_operation)),
193
+ field("location", optional($.trailing_location)),
194
+ ),
195
+
196
+ generic_operation: ($) =>
197
+ seq(
198
+ $.string_literal,
199
+ $._value_use_list_parens,
200
+ optional($._successor_list),
201
+ optional($.properties),
202
+ optional($._region_list),
203
+ optional($.attribute),
204
+ ":",
205
+ $.function_type,
206
+ ),
207
+
208
+ _op_result_list: ($) =>
209
+ seq($.op_result, repeat(seq(",", $.op_result)), "="),
210
+ op_result: ($) => seq($.value_use, optional(seq(":", $.integer_literal))),
211
+ _successor_list: ($) =>
212
+ seq("[", $.successor, repeat(seq(",", $.successor)), "]"),
213
+ successor: ($) => prec.right(seq($.caret_id, optional($._value_arg_list))),
214
+ _region_list: ($) => seq("(", $.region, repeat(seq(",", $.region)), ")"),
215
+ properties: ($) =>
216
+ seq(
217
+ "<{",
218
+ optional($.attribute_entry),
219
+ repeat(seq(",", $.attribute_entry)),
220
+ "}>",
221
+ ),
222
+ dictionary_attribute: ($) =>
223
+ seq(
224
+ "{",
225
+ optional($.attribute_entry),
226
+ repeat(seq(",", $.attribute_entry)),
227
+ "}",
228
+ ),
229
+ trailing_location: ($) => seq(token("loc"), "(", $.location, ")"),
134
230
  // LangRef "Source Locations": location ::= unknown | name | filelinecol |
135
231
  // filelocrange | callsite | fused | loc-alias-ref
136
- location: $ => choice(
137
- $.unknown_location,
138
- $._string_location,
139
- $.callsite_location,
140
- $.fused_location,
141
- $.attribute_alias,
142
- $.dialect_attribute,
143
- ),
144
- unknown_location: $ => token('unknown'),
145
- callsite_location: $ => seq(token('callsite'), '(',
146
- $.location, token('at'), $.location, ')'),
147
- fused_location: $ => seq(token('fused'),
148
- optional(seq('<', $.attribute_value, '>')),
149
- '[', $.location, repeat(seq(',', $.location)), ']'),
232
+ location: ($) =>
233
+ choice(
234
+ $.unknown_location,
235
+ $._string_location,
236
+ $.callsite_location,
237
+ $.fused_location,
238
+ $.attribute_alias,
239
+ $.dialect_attribute,
240
+ ),
241
+ unknown_location: ($) => token("unknown"),
242
+ callsite_location: ($) =>
243
+ seq(token("callsite"), "(", $.location, token("at"), $.location, ")"),
244
+ fused_location: ($) =>
245
+ seq(
246
+ token("fused"),
247
+ optional(seq("<", $.attribute_value, ">")),
248
+ "[",
249
+ $.location,
250
+ repeat(seq(",", $.location)),
251
+ "]",
252
+ ),
150
253
  // Combines name-location and filelinecol-location (LangRef uses the same
151
254
  // string-literal prefix; what follows distinguishes them).
152
- _string_location: $ => seq(
153
- $.string_literal,
154
- optional(choice(
155
- $._filelinecol_suffix,
156
- seq('(', $.location, ')'),
157
- )),
158
- ),
159
- _filelinecol_suffix: $ => seq(
160
- ':', $.integer_literal,
161
- optional(seq(':', $.integer_literal)),
162
- optional(seq(token('to'),
163
- optional($.integer_literal),
164
- ':', $.integer_literal)),
165
- ),
255
+ _string_location: ($) =>
256
+ seq(
257
+ $.string_literal,
258
+ optional(choice($._filelinecol_suffix, seq("(", $.location, ")"))),
259
+ ),
260
+ _filelinecol_suffix: ($) =>
261
+ seq(
262
+ ":",
263
+ $.integer_literal,
264
+ optional(seq(":", $.integer_literal)),
265
+ optional(
266
+ seq(token("to"), optional($.integer_literal), ":", $.integer_literal),
267
+ ),
268
+ ),
166
269
 
167
270
  // =========================================================================
168
271
  // Three-tier custom operation system
@@ -170,32 +273,66 @@ export default grammar({
170
273
  // Tier 1: func_operation, module_operation — structural ops for navigation
171
274
  // Tier 2: _generic_custom_operation — all other dialect.op_name patterns
172
275
  // =========================================================================
173
- custom_operation: $ => choice(
174
- prec(2, $.func_operation),
175
- prec(2, $.module_operation),
176
- prec(2, $._affine_for_operation),
177
- $._generic_custom_operation,
178
- ),
276
+ custom_operation: ($) =>
277
+ choice(
278
+ prec(2, $.func_operation),
279
+ prec(2, $.module_operation),
280
+ prec(2, $._affine_for_operation),
281
+ $._generic_custom_operation_with_location_attr_dict,
282
+ $._generic_custom_operation,
283
+ ),
179
284
 
180
285
  // Tier 1: Function operations (func.func, llvm.func)
181
286
  // Token prec 20 ensures these keywords win over _dotted_op_name (prec 10)
182
- func_operation: $ => prec.right(seq(
183
- field('name', choice(token(prec(20, 'func.func')), token(prec(20, 'llvm.func')))),
184
- field('visibility', optional(choice('private', 'public'))),
185
- field('sym_name', $.symbol_ref_id),
186
- field('arguments', $.func_arg_list),
187
- field('return', optional($.func_return)),
188
- field('attributes', optional(seq(optional(token('attributes')), $.dictionary_attribute))),
189
- field('body', optional($.region)),
190
- )),
287
+ func_operation: ($) =>
288
+ prec.right(
289
+ seq(
290
+ field(
291
+ "name",
292
+ choice(token(prec(20, "func.func")), token(prec(20, "llvm.func"))),
293
+ ),
294
+ field("visibility", optional(choice("private", "public"))),
295
+ // Optional leading specifier keywords between the function name and its
296
+ // symbol. Covers MLIR symbol visibility (`nested`) and the LLVM dialect's
297
+ // llvm.func linkage / calling-convention / unnamed_addr / visibility
298
+ // keywords (internal, external, linkonce, fastcc, amdgpu_kernelcc,
299
+ // local_unnamed_addr, hidden, ...). MLIR's CConv enum alone has ~50
300
+ // keywords, so rather than enumerate a brittle list we accept bare_id-
301
+ // shaped specifiers here; the trailing `@symbol` (symbol_ref_id) is an
302
+ // unambiguous terminator.
303
+ repeat(field("specifier", alias($.bare_id, $.function_specifier))),
304
+ field("sym_name", $.symbol_ref_id),
305
+ field("arguments", $.func_arg_list),
306
+ field("return", optional($.func_return)),
307
+ field(
308
+ "attributes",
309
+ optional(
310
+ seq(optional(token("attributes")), $.dictionary_attribute),
311
+ ),
312
+ ),
313
+ field("body", optional($.region)),
314
+ ),
315
+ ),
191
316
 
192
317
  // Tier 1: Module operations (module, builtin.module)
193
- module_operation: $ => prec.right(seq(
194
- field('name', choice(token(prec(20, 'builtin.module')), token(prec(20, 'module')))),
195
- field('sym_name', optional($.symbol_ref_id)),
196
- field('attributes', optional(seq(optional(token('attributes')), $.attribute))),
197
- field('body', $.region),
198
- )),
318
+ module_operation: ($) =>
319
+ prec.right(
320
+ seq(
321
+ field(
322
+ "name",
323
+ choice(
324
+ token(prec(20, "builtin.module")),
325
+ token(prec(20, "module")),
326
+ ),
327
+ ),
328
+ field("sym_name", optional($.symbol_ref_id)),
329
+ field(
330
+ "attributes",
331
+ optional(seq(optional(token("attributes")), $.attribute)),
332
+ ),
333
+ field("body", $.region),
334
+ ),
335
+ ),
199
336
 
200
337
  // affine.for prints its induction-variable location before the body
201
338
  // (`affine.for %i loc("iv") = 0 to 8 { ... } loc(...)`). The generic
@@ -203,21 +340,39 @@ export default grammar({
203
340
  // operation; without this structured rule, that machinery would bind the
204
341
  // induction loc to the operation slot and leave the operation's own
205
342
  // trailing loc unparseable.
206
- _affine_for_operation: $ => prec.right(seq(
207
- field('name', alias(token(prec(20, 'affine.for')), $.custom_op_name)),
208
- $.value_use,
209
- optional(field('induction_location', $.trailing_location)),
210
- repeat($._custom_body_element),
211
- )),
343
+ _affine_for_operation: ($) =>
344
+ prec.right(
345
+ seq(
346
+ field("name", alias(token(prec(20, "affine.for")), $.custom_op_name)),
347
+ $.value_use,
348
+ optional(field("induction_location", $.trailing_location)),
349
+ repeat($._custom_body_element),
350
+ ),
351
+ ),
212
352
 
213
353
  // Tier 2: Generic custom operation — dialect.op_name + structural body
214
354
  // Negative dynamic precedence makes the parser prefer ending the body
215
355
  // and starting a new operation (with _op_result_list) over extending
216
356
  // the body with more elements, when both paths are valid (GLR).
217
- _generic_custom_operation: $ => prec.dynamic(-1, prec.right(seq(
218
- field('name', $.custom_op_name),
219
- repeat($._custom_body_element),
220
- ))),
357
+ _generic_custom_operation: ($) =>
358
+ prec.dynamic(
359
+ -1,
360
+ prec.right(
361
+ seq(field("name", $.custom_op_name), repeat($._custom_body_element)),
362
+ ),
363
+ ),
364
+
365
+ _generic_custom_operation_with_location_attr_dict: ($) =>
366
+ prec.dynamic(
367
+ -1,
368
+ prec.right(
369
+ seq(
370
+ field("name", alias($._dotted_op_name, $.custom_op_name)),
371
+ $._custom_body_location_attr_dict,
372
+ repeat($._custom_body_element),
373
+ ),
374
+ ),
375
+ ),
221
376
 
222
377
  // Operation name: dotted form (arith.addi, scf.forall.in_parallel)
223
378
  // or known bare names (return, call, constant, etc.)
@@ -230,48 +385,154 @@ export default grammar({
230
385
  // prec.dynamic(-1) on _generic_custom_operation keeps bare_id as a body
231
386
  // element when inside a custom op body; it only acts as an op name at
232
387
  // region/block boundaries where operation+ is required.
233
- custom_op_name: $ => choice($._dotted_op_name, $._bare_op_name, $.bare_id),
234
- _dotted_op_name: $ => token(prec(10, seq(
235
- /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/),
236
- repeat1(seq('.', /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.]/))),
237
- ))),
388
+ custom_op_name: ($) =>
389
+ choice($._dotted_op_name, $._bare_op_name, $.bare_id),
390
+ _dotted_op_name: ($) =>
391
+ token(
392
+ prec(
393
+ 10,
394
+ seq(
395
+ /[a-zA-Z_]/,
396
+ repeat(/[a-zA-Z0-9_$]/),
397
+ repeat1(seq(".", /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.]/))),
398
+ ),
399
+ ),
400
+ ),
238
401
  // Bare operation names: spec-sanctioned no-prefix aliases only.
239
402
  // All other dialect ops go through _dotted_op_name or _generic_custom_operation.
240
- _bare_op_name: $ => token(prec(10, choice(
241
- 'return', 'call', 'call_indirect', 'constant', 'unrealized_conversion_cast',
242
- ))),
403
+ _bare_op_name: ($) =>
404
+ token(
405
+ prec(
406
+ 10,
407
+ choice(
408
+ "return",
409
+ "call",
410
+ "call_indirect",
411
+ "constant",
412
+ "unrealized_conversion_cast",
413
+ ),
414
+ ),
415
+ ),
243
416
 
244
417
  // Structural body elements that can appear in custom operation format.
245
418
  // These are recognized by sigils (%,^,@,!,#) or by structural delimiters.
246
- _custom_body_element: $ => choice(
247
- $.value_use, // %foo, %0
248
- $.symbol_ref_id, // @sym, @"string"
249
- $.successor, // ^bb0, ^bb0(%arg : type)
250
- prec(2, $.type), // !type, i32, memref<...>, etc.
251
- $.attribute, // #attr, {dict}, affine_map<...>
252
- $.region, // { ... } (regions with operations)
253
- $._custom_body_value_group, // {%v : type, ...}
254
- $._custom_body_paren, // ( ... )
255
- $._custom_body_bracket, // [ ... ]
256
- $._custom_body_angle_group, // < ... >
257
- $._literal, // 42, 3.14, "string", true, dense<...>
258
- 'array', // property names may collide with array<...>
259
- 'vector', // OpenACC keyword may collide with vector<...>
260
- 'ceildiv', 'floordiv', 'mod', // inline affine keywords
261
- $.bare_id, // keywords: to, from, step, ins, outs, etc.
262
- ',', '=', ':', '->', '*', '?', $.dimension_separator, '+', '-', '/', '&', '|', '~',
263
- ),
264
-
265
- _custom_body_paren: $ => seq('(', repeat($._nested_custom_body_element), ')'),
266
- _custom_body_bracket: $ => seq('[', repeat($._nested_custom_body_element), ']'),
267
- _custom_body_value_group: $ => seq('{', $.value_use, ':', $.type,
268
- repeat(seq(',', $.value_use, ':', $.type)), '}'),
269
- _custom_body_angle_group: $ => seq('<', repeat($._nested_custom_body_element), '>'),
419
+ _custom_body_element: ($) =>
420
+ choice(
421
+ $._custom_body_element_base,
422
+ $._custom_body_successor_marker, // >^bb1 (WasmSSA if continuation)
423
+ ),
424
+
425
+ _custom_body_element_base: ($) =>
426
+ choice(
427
+ $.value_use, // %foo, %0
428
+ $.symbol_ref_id, // @sym, @"string"
429
+ $.successor, // ^bb0, ^bb0(%arg : type)
430
+ $._custom_body_complex_label, // complex: %value (IRDL operand label)
431
+ prec(2, $.type), // !type, i32, memref<...>, etc.
432
+ $.attribute, // #attr, {dict}, affine_map<...>
433
+ $._custom_body_tuple_group, // {(%v), (%w)}
434
+ $.region, // { ... } (regions with operations)
435
+ $._custom_body_value_group, // {%v : type, ...}
436
+ $._custom_body_ssa_dict, // {"attr" = %value, ...} / options with SSA values
437
+ $._custom_body_sparse_operand, // sparse(%idx : type)
438
+ $._custom_body_paren, // ( ... )
439
+ $._custom_body_bracket, // [ ... ]
440
+ $._custom_body_angle_group, // < ... >
441
+ $._literal, // 42, 3.14, "string", true, dense<...>
442
+ "array", // property names may collide with array<...>
443
+ "vector", // OpenACC keyword may collide with vector<...>
444
+ "tensor", // AMDGPU/NVGPU keyword may collide with tensor<...>
445
+ "ceildiv",
446
+ "floordiv",
447
+ "mod", // inline affine keywords
448
+ $.bare_id, // keywords: to, from, step, ins, outs, etc.
449
+ $._custom_body_arrow, // <- (mapped-from, e.g. omp.fuse <- (...))
450
+ ",",
451
+ "=",
452
+ ":",
453
+ "->",
454
+ "*",
455
+ "?",
456
+ $.dimension_separator,
457
+ "+",
458
+ "-",
459
+ "/",
460
+ "&",
461
+ "|",
462
+ "~",
463
+ ),
464
+
465
+ _custom_body_paren: ($) =>
466
+ seq("(", repeat($._nested_custom_body_element), ")"),
467
+ _custom_body_bracket: ($) =>
468
+ seq("[", repeat($._nested_custom_body_element), "]"),
469
+ _custom_body_value_group: ($) =>
470
+ seq(
471
+ "{",
472
+ $.value_use,
473
+ ":",
474
+ $.type,
475
+ repeat(seq(",", $.value_use, ":", $.type)),
476
+ "}",
477
+ ),
478
+ _custom_body_tuple_group: ($) =>
479
+ seq(
480
+ "{",
481
+ $._custom_body_tuple,
482
+ repeat(seq(",", $._custom_body_tuple)),
483
+ "}",
484
+ ),
485
+ _custom_body_tuple: ($) => seq("(", $._value_use_list, ")"),
486
+ _custom_body_location_attr_dict: ($) =>
487
+ seq($.trailing_location, $.dictionary_attribute),
488
+ _custom_body_complex_label: ($) =>
489
+ prec(1, seq($._complex_label_start, $.value_use)),
490
+ _custom_body_ssa_dict: ($) =>
491
+ seq(
492
+ "{",
493
+ repeat(seq($._custom_body_attr_dict_entry, ",")),
494
+ $._custom_body_ssa_dict_entry,
495
+ repeat(seq(",", $._custom_body_mixed_dict_entry)),
496
+ "}",
497
+ ),
498
+ _custom_body_dict_key: ($) => $.string_literal,
499
+ _custom_body_attr_dict_entry: ($) =>
500
+ seq($._custom_body_dict_key, "=", $.attribute_value),
501
+ _custom_body_ssa_dict_entry: ($) =>
502
+ seq(
503
+ $._custom_body_dict_key,
504
+ "=",
505
+ choice($.value_use, $._custom_body_ssa_value_array),
506
+ ),
507
+ _custom_body_mixed_dict_entry: ($) =>
508
+ seq(
509
+ $._custom_body_dict_key,
510
+ "=",
511
+ choice($.attribute_value, $.value_use, $._custom_body_ssa_value_array),
512
+ ),
513
+ _custom_body_ssa_value_array: ($) =>
514
+ seq("[", $.value_use, repeat(seq(",", $.value_use)), "]"),
515
+ _custom_body_successor_marker: ($) => seq(">", $.successor),
516
+ _custom_body_sparse_operand: ($) =>
517
+ seq($._sparse_keyword, $._custom_body_paren),
518
+ _custom_body_angle_group: ($) =>
519
+ seq("<", repeat($._nested_custom_body_element), ">"),
520
+ // "Mapped-from" arrow used by OpenMP loop-transform ops, e.g.
521
+ // omp.fuse(%fused) <- (%loop0, %loop1)
522
+ // omp.tile(%grid, %intratile) <- (%loop) sizes(%ts : i32)
523
+ // Deliberately built from the existing single-char '<' and '-' tokens
524
+ // rather than a combined '<-' token: a length-2 '<-' token would win
525
+ // tree-sitter's longest-match at a dialect-attribute body boundary and
526
+ // mis-lex negative payloads like `#smt.bv<-1>` as `<-` `1`. Keeping the
527
+ // tokens separate leaves the lexer unchanged; GLR distinguishes the arrow
528
+ // from `_custom_body_angle_group` (which requires a closing '>').
529
+ _custom_body_arrow: ($) => seq("<", "-"),
270
530
  // Only nested groups accept `trailing_location` as a body element.
271
531
  // At the top level it is omitted on purpose so the operation rule
272
532
  // captures a trailing `loc(...)` as the operation's location instead of
273
533
  // it being swallowed by the body repetition.
274
- _nested_custom_body_element: $ => choice($._custom_body_element, $.trailing_location),
534
+ _nested_custom_body_element: ($) =>
535
+ choice($._custom_body_element_base, $.trailing_location),
275
536
 
276
537
  // =========================================================================
277
538
  // Blocks
@@ -279,232 +540,532 @@ export default grammar({
279
540
  // block-label ::= block-id block-arg-list? `:`
280
541
  // caret-id ::= `^` suffix-id
281
542
  // =========================================================================
282
- block: $ => seq($.block_label, repeat($.operation)),
283
- block_label: $ => seq($._block_id, optional($.block_arg_list), ':'),
284
- _block_id: $ => $.caret_id,
285
- caret_id: $ => seq('^', $._suffix_id),
286
- _value_use_and_type: $ => seq($.value_use, optional(seq(':', $.type)),
287
- optional($.trailing_location)),
288
- _value_use_and_type_list: $ => seq($._value_use_and_type,
289
- repeat(seq(',', $._value_use_and_type))),
290
- block_arg_list: $ => seq('(', optional($._value_use_and_type_list), ')'),
291
- _value_arg_list: $ => seq('(', optional(choice(
292
- $._value_use_type_list, // bulk format: (%v0, %v1 : t0, t1)
293
- $._value_use_and_type_list, // per-pair format: (%v0 : t0, %v1 : t1)
294
- )), ')'),
295
- _value_use_type_list: $ => seq($._value_use_list, ':', $._type_list_no_parens),
543
+ block: ($) => seq($.block_label, repeat($.operation)),
544
+ block_label: ($) => seq($._block_id, optional($.block_arg_list), ":"),
545
+ _block_id: ($) => $.caret_id,
546
+ caret_id: ($) => seq("^", $._suffix_id),
547
+ _value_use_and_type: ($) =>
548
+ seq(
549
+ $.value_use,
550
+ optional(seq(":", $.type)),
551
+ optional($.trailing_location),
552
+ ),
553
+ _value_use_and_type_list: ($) =>
554
+ seq($._value_use_and_type, repeat(seq(",", $._value_use_and_type))),
555
+ block_arg_list: ($) => seq("(", optional($._value_use_and_type_list), ")"),
556
+ _value_arg_list: ($) =>
557
+ seq(
558
+ "(",
559
+ optional(
560
+ choice(
561
+ $._value_use_type_list, // bulk format: (%v0, %v1 : t0, t1)
562
+ $._value_use_and_type_list, // per-pair format: (%v0 : t0, %v1 : t1)
563
+ ),
564
+ ),
565
+ ")",
566
+ ),
567
+ _value_use_type_list: ($) =>
568
+ seq($._value_use_list, ":", $._type_list_no_parens),
296
569
 
297
570
  // =========================================================================
298
571
  // Regions
299
572
  // region ::= `{` entry-block? block* `}`
300
573
  // entry-block ::= operation+
301
574
  // =========================================================================
302
- region: $ => seq('{', optional($.entry_block), repeat($.block), '}'),
303
- entry_block: $ => repeat1($.operation),
575
+ region: ($) => seq("{", optional($.entry_block), repeat($.block), "}"),
576
+ entry_block: ($) => repeat1($.operation),
304
577
 
305
578
  // =========================================================================
306
579
  // Types
307
580
  // type ::= type-alias | dialect-type | builtin-type
308
581
  // function-type ::= (type | type-list-parens) `->` (type | type-list-parens)
309
582
  // =========================================================================
310
- type: $ => choice($.type_alias, $.dialect_type, $.builtin_type),
311
- _type_list_no_parens: $ => prec.left(seq(choice($.type, $.function_type),
312
- repeat(seq(',', choice($.type, $.function_type))))),
313
- _type_list_parens: $ => seq('(', optional($._type_list_no_parens), ')'),
314
- function_type: $ => seq(choice($.type, $._type_list_parens), $._function_return),
315
- _function_return: $ => seq(token('->'), choice($.type, $._type_list_parens)),
316
- _type_annotation: $ => seq(':', $._type_list_no_parens),
317
- _function_type_annotation: $ => seq(':', $.function_type),
318
- _literal_and_type: $ => seq($._literal, optional($._type_annotation)),
583
+ type: ($) => choice($.type_alias, $.dialect_type, $.builtin_type),
584
+ _type_list_no_parens: ($) =>
585
+ prec.left(
586
+ seq(
587
+ choice($.type, $.function_type),
588
+ repeat(seq(",", choice($.type, $.function_type))),
589
+ ),
590
+ ),
591
+ _type_list_parens: ($) => seq("(", optional($._type_list_no_parens), ")"),
592
+ function_type: ($) =>
593
+ seq(choice($.type, $._type_list_parens), $._function_return),
594
+ _function_return: ($) =>
595
+ seq(token("->"), choice($.type, $._type_list_parens)),
596
+ _type_annotation: ($) => seq(":", $._type_list_no_parens),
597
+ _function_type_annotation: ($) => seq(":", $.function_type),
598
+ _literal_and_type: ($) => seq($._literal, optional($._type_annotation)),
319
599
 
320
600
  // Type aliases
321
- type_alias_def: $ => seq('!', $._alias_or_dialect_id, '=', $.type),
322
- type_alias: $ => seq('!', $._alias_or_dialect_id),
601
+ type_alias_def: ($) => seq("!", $._alias_or_dialect_id, "=", $.type),
602
+ type_alias: ($) => seq("!", $._alias_or_dialect_id),
323
603
 
324
604
  // Dialect Types
325
- dialect_type: $ => seq(
326
- '!', choice($.opaque_dialect_item, $.pretty_dialect_item, $.parametric_dialect_item)),
327
- dialect_namespace: $ => $._alias_or_dialect_id,
328
- dialect_ident: $ => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.-]/))),
329
- opaque_dialect_item: $ => prec(1, seq($.dialect_namespace, '<', $.string_literal, '>')),
330
- pretty_dialect_item: $ => seq($.dialect_namespace, '.', $.dialect_ident,
331
- optional($.pretty_dialect_item_body)),
605
+ dialect_type: ($) =>
606
+ seq(
607
+ "!",
608
+ choice(
609
+ $.opaque_dialect_item,
610
+ $.pretty_dialect_item,
611
+ $.parametric_dialect_item,
612
+ ),
613
+ ),
614
+ dialect_namespace: ($) => $._alias_or_dialect_id,
615
+ dialect_ident: ($) => token(seq(/[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.-]/))),
616
+ opaque_dialect_item: ($) =>
617
+ prec(1, seq($.dialect_namespace, "<", $.string_literal, ">")),
618
+ pretty_dialect_item: ($) =>
619
+ seq(
620
+ $.dialect_namespace,
621
+ ".",
622
+ $.dialect_ident,
623
+ optional($.pretty_dialect_item_body),
624
+ ),
332
625
  // Parametric dialect item: !namespace<...> or #namespace<...> without dot-separated ident
333
- parametric_dialect_item: $ => seq($.dialect_namespace, $.pretty_dialect_item_body),
334
- pretty_dialect_item_body: $ => seq('<', repeat($._pretty_dialect_item_contents), '>'),
335
- _pretty_dialect_item_contents: $ => prec.left(choice(
336
- $.pretty_dialect_item_body,
337
- $._pretty_dialect_bang_body_token,
338
- $._pretty_dialect_body_attribute,
339
- $.dialect_dim_list,
340
- $.type,
341
- prec(2, $.attribute),
342
- $._literal,
343
- 'dense', 'sparse', 'array', 'vector',
344
- $.bare_id,
345
- ',', ':', '=', '->', '(', ')', '[', ']', '{', '}', '*', '?',
346
- '@', '#',
347
- token(prec(-1, /[^<>]/))
348
- )),
349
- _pretty_dialect_bang_body_token: $ => token(prec(1,
350
- seq('!', /[^a-zA-Z_<>]/))),
351
- _pretty_dialect_body_attribute: $ => choice(
352
- alias($._pretty_dialect_attribute_token, $.dialect_attribute),
353
- alias($._pretty_attribute_alias_token, $.attribute_alias)),
354
- _pretty_attribute_alias_token: $ => token(prec(2,
355
- seq('#', /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/)))),
356
- _pretty_dialect_attribute_token: $ => token(prec(2,
357
- seq('#', /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/), '.',
358
- /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$.-]/)))),
359
- dimension_separator: $ => token(prec(10, 'x')),
360
- dialect_dim_list: $ => prec.dynamic(1, seq($._dialect_dim_primitive,
361
- repeat1(seq($.dimension_separator, $._dialect_dim_primitive)))),
362
- _dialect_dim_primitive: $ => choice(
363
- prec(1, $.type),
364
- alias($.integer_literal, $.dimension_size),
365
- '?',
366
- '*'),
626
+ parametric_dialect_item: ($) =>
627
+ seq($.dialect_namespace, $.pretty_dialect_item_body),
628
+ pretty_dialect_item_body: ($) =>
629
+ seq("<", repeat($._pretty_dialect_item_contents), ">"),
630
+ _pretty_dialect_item_contents: ($) =>
631
+ prec.left(
632
+ choice(
633
+ $.pretty_dialect_item_body,
634
+ $._pretty_dialect_bang_body_token,
635
+ $._pretty_dialect_body_attribute,
636
+ $.dialect_dim_list,
637
+ $.type,
638
+ prec(2, $.attribute),
639
+ $._literal,
640
+ $._dense_keyword,
641
+ $._sparse_keyword,
642
+ "array",
643
+ "vector",
644
+ "tensor",
645
+ "opaque",
646
+ $.bare_id,
647
+ ",",
648
+ ":",
649
+ "=",
650
+ "->",
651
+ "(",
652
+ ")",
653
+ "[",
654
+ "]",
655
+ "{",
656
+ "}",
657
+ "*",
658
+ "?",
659
+ "@",
660
+ "#",
661
+ token(prec(-1, /[^<>]/)),
662
+ ),
663
+ ),
664
+ _pretty_dialect_bang_body_token: ($) =>
665
+ token(prec(1, seq("!", /[^a-zA-Z_<>]/))),
666
+ _pretty_dialect_body_attribute: ($) =>
667
+ choice(
668
+ alias($._pretty_dialect_attribute_token, $.dialect_attribute),
669
+ alias($._pretty_attribute_alias_token, $.attribute_alias),
670
+ ),
671
+ _pretty_attribute_alias_token: ($) =>
672
+ token(prec(2, seq("#", /[a-zA-Z_]/, repeat(/[a-zA-Z0-9_$]/)))),
673
+ _pretty_dialect_attribute_token: ($) =>
674
+ token(
675
+ prec(
676
+ 2,
677
+ seq(
678
+ "#",
679
+ /[a-zA-Z_]/,
680
+ repeat(/[a-zA-Z0-9_$]/),
681
+ ".",
682
+ /[a-zA-Z_]/,
683
+ repeat(/[a-zA-Z0-9_$.-]/),
684
+ ),
685
+ ),
686
+ ),
687
+ dimension_separator: ($) => token(prec(10, "x")),
688
+ dialect_dim_list: ($) =>
689
+ prec.dynamic(
690
+ 1,
691
+ seq(
692
+ $._dialect_dim_primitive,
693
+ repeat1(seq($.dimension_separator, $._dialect_dim_primitive)),
694
+ ),
695
+ ),
696
+ _dialect_dim_primitive: ($) =>
697
+ choice(
698
+ prec(1, $.type),
699
+ prec(1, $._pretty_dialect_body_type),
700
+ alias($.integer_literal, $.dimension_size),
701
+ "?",
702
+ "*",
703
+ ),
704
+ _pretty_dialect_body_type: ($) =>
705
+ seq(choice($.bare_id, "array"), $.pretty_dialect_item_body),
367
706
 
368
707
  // Builtin types
369
- builtin_type: $ => choice(
370
- $.integer_type,
371
- $.float_type,
372
- $.complex_type,
373
- $.index_type,
374
- $.memref_type,
375
- $.none_type,
376
- $.tensor_type,
377
- $.vector_type,
378
- $.tuple_type,
379
- $.opaque_type),
380
-
381
- integer_type: $ => token(prec(5, seq(choice('si', 'ui', 'i'), /[0-9]/, repeat(/[0-9]/)))),
382
- float_type: $ => token(prec(5, choice('f16', 'tf32', 'f32', 'f64', 'f80', 'f128', 'bf16',
383
- 'f4E2M1FN', 'f6E2M3FN', 'f6E3M2FN', 'f8E3M4', 'f8E4M3', 'f8E4M3FN', 'f8E4M3FNUZ',
384
- 'f8E4M3B11FNUZ', 'f8E5M2', 'f8E5M2FNUZ', 'f8E8M0FNU'))),
385
- index_type: $ => token(prec(5, 'index')),
386
- none_type: $ => token(prec(5, 'none')),
387
- complex_type: $ => seq(token('complex'), '<', $._prim_type, '>'),
388
- _prim_type: $ => choice($.integer_type, $.float_type, $.index_type,
389
- $.complex_type, $.none_type, $.memref_type, $.vector_type, $.tensor_type,
390
- $.tuple_type, $.opaque_type, $.dialect_type, $.type_alias),
391
-
392
- memref_type: $ => seq(token('memref'), '<',
393
- field('dimension_list', $.dim_list),
394
- optional(seq(',', $.attribute_value)),
395
- optional(seq(',', $.attribute_value)), '>'),
396
- dim_list: $ => seq($._dim_primitive, repeat(seq('x', $._dim_primitive))),
708
+ builtin_type: ($) =>
709
+ choice(
710
+ $.integer_type,
711
+ $.float_type,
712
+ $.complex_type,
713
+ $.index_type,
714
+ $.memref_type,
715
+ $.none_type,
716
+ $.tensor_type,
717
+ $.vector_type,
718
+ $.tuple_type,
719
+ $.opaque_type,
720
+ ),
721
+
722
+ integer_type: ($) =>
723
+ token(prec(5, seq(choice("si", "ui", "i"), /[0-9]/, repeat(/[0-9]/)))),
724
+ float_type: ($) =>
725
+ token(
726
+ prec(
727
+ 5,
728
+ choice(
729
+ "f16",
730
+ "tf32",
731
+ "f32",
732
+ "f64",
733
+ "f80",
734
+ "f128",
735
+ "bf16",
736
+ "f4E2M1FN",
737
+ "f6E2M3FN",
738
+ "f6E3M2FN",
739
+ "f8E3M4",
740
+ "f8E4M3",
741
+ "f8E4M3FN",
742
+ "f8E4M3FNUZ",
743
+ "f8E4M3B11FNUZ",
744
+ "f8E5M2",
745
+ "f8E5M2FNUZ",
746
+ "f8E8M0FNU",
747
+ ),
748
+ ),
749
+ ),
750
+ index_type: ($) => token(prec(5, "index")),
751
+ none_type: ($) => token(prec(5, "none")),
752
+ complex_type: ($) => seq($._complex_type_start, $._prim_type, ">"),
753
+ _prim_type: ($) =>
754
+ choice(
755
+ $.integer_type,
756
+ $.float_type,
757
+ $.index_type,
758
+ $.complex_type,
759
+ $.none_type,
760
+ $.memref_type,
761
+ $.vector_type,
762
+ $.tensor_type,
763
+ $.tuple_type,
764
+ $.opaque_type,
765
+ $.dialect_type,
766
+ $.type_alias,
767
+ ),
768
+
769
+ memref_type: ($) =>
770
+ seq(
771
+ token("memref"),
772
+ "<",
773
+ field("dimension_list", $.dim_list),
774
+ optional(seq(",", $.attribute_value)),
775
+ optional(seq(",", $.attribute_value)),
776
+ ">",
777
+ ),
778
+ dim_list: ($) => seq($._dim_primitive, repeat(seq("x", $._dim_primitive))),
397
779
  // '*' represents the unranked form for both memref and tensor types
398
780
  // (UnrankedMemRefType, UnrankedTensorType). Vector uses its own
399
781
  // vector_dim_list / _static_dim_list and disallows '*' by construction.
400
- dimension_size: $ => token(repeat1(/[0-9]/)),
401
- _dim_primitive: $ => choice(prec(1, $.type), $.dimension_size, '?', '*'),
782
+ dimension_size: ($) => token(repeat1(/[0-9]/)),
783
+ _dim_primitive: ($) => choice(prec(1, $.type), $.dimension_size, "?", "*"),
402
784
 
403
- tensor_type: $ => seq(token('tensor'), '<', $.dim_list,
404
- optional(seq(',', $.tensor_encoding)), '>'),
405
- tensor_encoding: $ => $.attribute_value,
785
+ tensor_type: ($) =>
786
+ seq(
787
+ token("tensor"),
788
+ "<",
789
+ $.dim_list,
790
+ optional(seq(",", $.tensor_encoding)),
791
+ ">",
792
+ ),
793
+ tensor_encoding: ($) => $.attribute_value,
406
794
 
407
- vector_type: $ => prec(1, seq(token('vector'), '<', repeat($.vector_dim_list), $._prim_type, '>')),
408
- vector_dim_list: $ => prec.left(choice(seq($._static_dim_list, 'x',
409
- optional(seq('[', $._static_dim_list, ']', 'x'))), seq('[', $._static_dim_list, ']', 'x'))),
410
- _static_dim_list: $ => seq($.dimension_size, repeat(seq('x', $.dimension_size))),
795
+ vector_type: ($) =>
796
+ prec(
797
+ 1,
798
+ seq(token("vector"), "<", repeat($.vector_dim_list), $._prim_type, ">"),
799
+ ),
800
+ vector_dim_list: ($) =>
801
+ prec.left(
802
+ choice(
803
+ seq(
804
+ $._static_dim_list,
805
+ "x",
806
+ optional(seq("[", $._static_dim_list, "]", "x")),
807
+ ),
808
+ seq("[", $._static_dim_list, "]", "x"),
809
+ ),
810
+ ),
811
+ _static_dim_list: ($) =>
812
+ seq($.dimension_size, repeat(seq("x", $.dimension_size))),
411
813
 
412
- tuple_type: $ => seq(token('tuple'), '<', optional(seq($.tuple_dim, repeat(seq(',', $.tuple_dim)))), '>'),
413
- tuple_dim: $ => $._prim_type,
814
+ tuple_type: ($) =>
815
+ seq(
816
+ token("tuple"),
817
+ "<",
818
+ optional(seq($.tuple_dim, repeat(seq(",", $.tuple_dim)))),
819
+ ">",
820
+ ),
821
+ tuple_dim: ($) => $._prim_type,
414
822
 
415
823
  // opaque-type ::= `opaque` `<` string-literal `,` string-literal `>`
416
824
  // e.g. opaque<"llvm", "struct<(i32, float)>">
417
- opaque_type: $ => seq(token('opaque'), '<', $.string_literal, ',', $.string_literal, '>'),
825
+ opaque_type: ($) =>
826
+ seq(token("opaque"), "<", $.string_literal, ",", $.string_literal, ">"),
418
827
 
419
828
  // =========================================================================
420
829
  // Attributes
421
830
  // attribute-entry ::= (bare-id | string-literal) `=` attribute-value
422
831
  // attribute-value ::= attribute-alias | dialect-attribute | builtin-attribute
423
832
  // =========================================================================
424
- attribute_entry: $ => choice(
425
- seq(choice($.bare_id, $.string_literal), optional(seq('=', $.attribute_value))),
426
- // Array-valued entry (e.g. {["op.name"]} in transform dialect)
427
- seq('[', optional($._attribute_value_nobracket),
428
- repeat(seq(',', $._attribute_value_nobracket)), ']'),
429
- ),
430
- attribute_value: $ => choice(seq('[', optional($._attribute_value_nobracket),
431
- repeat(seq(',', $._attribute_value_nobracket)), ']'), $._attribute_value_nobracket),
432
- _attribute_value_nobracket: $ => choice($.attribute_alias, $.dialect_attribute,
433
- $.builtin_attribute, $.dictionary_attribute, $._literal_and_type, $.type,
434
- $.function_type, $._affine_map_like, $.symbol_ref_id, $.trailing_location,
435
- seq(choice($.attribute_alias, $.dialect_attribute, $.builtin_attribute), $._type_annotation)),
436
- attribute: $ => choice($.attribute_alias, $.dialect_attribute,
437
- $.builtin_attribute, $.dictionary_attribute),
833
+ attribute_entry: ($) =>
834
+ choice(
835
+ seq(
836
+ choice($.bare_id, $.string_literal),
837
+ optional(seq("=", $.attribute_value)),
838
+ ),
839
+ // Array-valued entry (e.g. {["op.name"]} in transform dialect)
840
+ $._attribute_array,
841
+ ),
842
+ attribute_value: ($) =>
843
+ choice($._attribute_array, $._attribute_value_nobracket),
844
+ _attribute_array: ($) =>
845
+ seq(
846
+ "[",
847
+ optional($._attribute_array_element),
848
+ repeat(seq(",", $._attribute_array_element)),
849
+ "]",
850
+ ),
851
+ _attribute_array_element: ($) =>
852
+ choice($._attribute_array, $._attribute_value_nobracket),
853
+ _attribute_value_nobracket: ($) =>
854
+ choice(
855
+ $.attribute_alias,
856
+ $.dialect_attribute,
857
+ $.builtin_attribute,
858
+ $.dictionary_attribute,
859
+ $._literal_and_type,
860
+ $.type,
861
+ $.function_type,
862
+ $._affine_map_like,
863
+ $.symbol_ref_id,
864
+ $.trailing_location,
865
+ seq(
866
+ choice($.attribute_alias, $.dialect_attribute, $.builtin_attribute),
867
+ $._type_annotation,
868
+ ),
869
+ ),
870
+ attribute: ($) =>
871
+ choice(
872
+ $.attribute_alias,
873
+ $.dialect_attribute,
874
+ $.builtin_attribute,
875
+ $.dictionary_attribute,
876
+ ),
438
877
 
439
878
  // Attribute aliases
440
- attribute_alias_def: $ => seq('#', $._alias_or_dialect_id, '=', $.attribute_value),
441
- attribute_alias: $ => seq('#', $._alias_or_dialect_id),
879
+ attribute_alias_def: ($) =>
880
+ seq("#", $._alias_or_dialect_id, "=", $.attribute_value),
881
+ attribute_alias: ($) => seq("#", $._alias_or_dialect_id),
442
882
 
443
883
  // Dialect attributes
444
- dialect_attribute: $ => seq('#', choice($.opaque_dialect_item, $.pretty_dialect_item, $.parametric_dialect_item)),
884
+ dialect_attribute: ($) =>
885
+ seq(
886
+ "#",
887
+ choice(
888
+ $.opaque_dialect_item,
889
+ $.pretty_dialect_item,
890
+ $.parametric_dialect_item,
891
+ ),
892
+ ),
445
893
 
446
894
  // Builtin attributes
447
- builtin_attribute: $ => choice(
448
- $.strided_layout,
449
- prec(1, $.affine_map),
450
- prec(1, $.affine_set),
451
- $.dense_resource_literal,
452
- ),
453
- dense_resource_literal: $ => seq(token('dense_resource'), '<',
454
- choice($.bare_id, $.string_literal), '>'),
455
- strided_layout: $ => seq(token('strided'), '<', '[', optional($._stride_list_comma), ']',
456
- optional(seq(',', token('offset'), ':', $._stride_primitive)), '>'),
457
- _stride_list_comma: $ => seq($._stride_primitive, repeat(seq(',', $._stride_primitive))),
458
- _stride_primitive: $ => choice($.integer_literal, '?', '*'),
895
+ builtin_attribute: ($) =>
896
+ choice(
897
+ $.strided_layout,
898
+ prec(1, $.affine_map),
899
+ prec(1, $.affine_set),
900
+ $.dense_resource_literal,
901
+ $.distinct_attribute,
902
+ ),
903
+ dense_resource_literal: ($) =>
904
+ seq(
905
+ token(prec(2, "dense_resource")),
906
+ "<",
907
+ choice($.bare_id, $.string_literal),
908
+ ">",
909
+ ),
910
+ distinct_attribute: ($) =>
911
+ seq(
912
+ token("distinct"),
913
+ "[",
914
+ alias($._unsigned_integer_literal, $.integer_literal),
915
+ "]",
916
+ "<",
917
+ optional($.attribute_value),
918
+ ">",
919
+ ),
920
+ strided_layout: ($) =>
921
+ seq(
922
+ token("strided"),
923
+ "<",
924
+ "[",
925
+ optional($._stride_list_comma),
926
+ "]",
927
+ optional(seq(",", token("offset"), ":", $._stride_primitive)),
928
+ ">",
929
+ ),
930
+ _stride_list_comma: ($) =>
931
+ seq($._stride_primitive, repeat(seq(",", $._stride_primitive))),
932
+ _stride_primitive: ($) => choice($.integer_literal, "?", "*"),
459
933
 
460
934
  // =========================================================================
461
935
  // Affine expressions
462
936
  // =========================================================================
463
- affine_map: $ => seq(token('affine_map'), '<', $._multi_dim_affine_expr_parens,
464
- optional($._multi_dim_affine_expr_sq), token('->'), $._multi_dim_affine_expr_parens, '>'),
465
- _affine_map_like: $ => seq($._multi_dim_affine_expr_parens,
466
- optional($._multi_dim_affine_expr_sq), token('->'), $._multi_dim_affine_expr_parens),
467
- affine_set: $ => seq(token('affine_set'), '<', $._multi_dim_affine_expr_parens,
468
- optional($._multi_dim_affine_expr_sq), ':', $._multi_dim_affine_expr_parens, '>'),
469
- _multi_dim_affine_expr_parens: $ => seq('(', optional($._multi_dim_affine_expr), ')'),
470
- _multi_dim_affine_expr_sq: $ => seq('[', optional($._multi_dim_affine_expr), ']'),
471
-
472
- _multi_dim_affine_expr: $ => seq($._affine_expr, repeat(seq(',', $._affine_expr))),
473
- _affine_expr: $ => choice(
474
- seq('(', $._affine_expr, ')'),
475
- prec(4, seq('-', $._affine_expr)),
476
- prec.left(3, seq($._affine_expr, choice('*', 'ceildiv', 'floordiv', 'mod'), $._affine_expr)),
477
- prec.left(2, seq($._affine_expr, choice('+', '-'), $._affine_expr)),
478
- prec.left(1, seq($._affine_expr, choice('==', '>=', '<='), $._affine_expr)),
479
- $._affine_prim
480
- ),
481
- _affine_prim: $ => choice($.integer_literal, $.value_use,
482
- seq(choice($.bare_id, 'dense', 'sparse'), optional(seq(':', choice($.bare_id, 'dense', 'sparse', 'compressed', 'singleton', 'loose_compressed', 'n_out_of_m')))),
483
- seq('symbol', '(', $.value_use, ')'), seq(choice('max', 'min'), '(', $._value_use_list, ')')),
937
+ affine_map: ($) =>
938
+ seq(
939
+ token("affine_map"),
940
+ "<",
941
+ $._multi_dim_affine_expr_parens,
942
+ optional($._multi_dim_affine_expr_sq),
943
+ token("->"),
944
+ $._multi_dim_affine_expr_parens,
945
+ ">",
946
+ ),
947
+ _affine_map_like: ($) =>
948
+ seq(
949
+ $._multi_dim_affine_expr_parens,
950
+ optional($._multi_dim_affine_expr_sq),
951
+ token("->"),
952
+ $._multi_dim_affine_expr_parens,
953
+ ),
954
+ affine_set: ($) =>
955
+ seq(
956
+ token("affine_set"),
957
+ "<",
958
+ $._multi_dim_affine_expr_parens,
959
+ optional($._multi_dim_affine_expr_sq),
960
+ ":",
961
+ $._multi_dim_affine_expr_parens,
962
+ ">",
963
+ ),
964
+ _multi_dim_affine_expr_parens: ($) =>
965
+ seq("(", optional($._multi_dim_affine_expr), ")"),
966
+ _multi_dim_affine_expr_sq: ($) =>
967
+ seq("[", optional($._multi_dim_affine_expr), "]"),
968
+
969
+ _multi_dim_affine_expr: ($) =>
970
+ seq($._affine_expr, repeat(seq(",", $._affine_expr))),
971
+ _affine_expr: ($) =>
972
+ choice(
973
+ seq("(", $._affine_expr, ")"),
974
+ prec(4, seq("-", $._affine_expr)),
975
+ prec.left(
976
+ 3,
977
+ seq(
978
+ $._affine_expr,
979
+ choice("*", "ceildiv", "floordiv", "mod"),
980
+ $._affine_expr,
981
+ ),
982
+ ),
983
+ prec.left(2, seq($._affine_expr, choice("+", "-"), $._affine_expr)),
984
+ prec.left(
985
+ 1,
986
+ seq($._affine_expr, choice("==", ">=", "<="), $._affine_expr),
987
+ ),
988
+ $._affine_prim,
989
+ ),
990
+ _affine_prim: ($) =>
991
+ choice(
992
+ $.integer_literal,
993
+ $.value_use,
994
+ seq(
995
+ choice($.bare_id, $._dense_keyword, $._sparse_keyword),
996
+ optional(
997
+ seq(
998
+ ":",
999
+ choice(
1000
+ $.bare_id,
1001
+ $._dense_keyword,
1002
+ $._sparse_keyword,
1003
+ "compressed",
1004
+ "singleton",
1005
+ "loose_compressed",
1006
+ "n_out_of_m",
1007
+ ),
1008
+ ),
1009
+ ),
1010
+ ),
1011
+ seq("symbol", "(", $.value_use, ")"),
1012
+ seq(choice("max", "min"), "(", $._value_use_list, ")"),
1013
+ ),
484
1014
 
485
1015
  // =========================================================================
486
1016
  // Function-related rules (used by func_operation tier-1)
487
1017
  // =========================================================================
488
- func_return: $ => seq(token('->'), $.type_list_attr_parens),
489
- func_arg_list: $ => seq('(', optional(choice($.variadic,
490
- $._value_id_and_type_attr_list)), ')'),
491
- _value_id_and_type_attr_list: $ => seq($._value_id_and_type_attr,
492
- repeat(seq(',', $._value_id_and_type_attr)), optional(seq(',', $.variadic))),
493
- _value_id_and_type_attr: $ => seq($._function_arg, optional($.attribute),
494
- optional($.trailing_location)),
495
- _function_arg: $ => choice(seq($.value_use, ':', choice($.type, $.function_type)), $.value_use, $.type, $.function_type),
496
- _type_or_func_type: $ => choice($.type, $.function_type),
497
- type_list_attr_parens: $ => choice($.type, $.function_type,
498
- seq('(', $._type_or_func_type, optional($.attribute),
499
- repeat(seq(',', $._type_or_func_type, optional($.attribute))), ')'), seq('(', ')')),
500
- variadic: $ => token('...'),
1018
+ func_return: ($) => seq(token("->"), $.type_list_attr_parens),
1019
+ func_arg_list: ($) =>
1020
+ seq(
1021
+ "(",
1022
+ optional(choice($.variadic, $._value_id_and_type_attr_list)),
1023
+ ")",
1024
+ ),
1025
+ _value_id_and_type_attr_list: ($) =>
1026
+ seq(
1027
+ $._value_id_and_type_attr,
1028
+ repeat(seq(",", choice($._value_id_and_type_attr, $.variadic))),
1029
+ ),
1030
+ _value_id_and_type_attr: ($) =>
1031
+ seq(
1032
+ $._function_arg,
1033
+ optional($.attribute),
1034
+ optional($.trailing_location),
1035
+ ),
1036
+ _function_arg: ($) =>
1037
+ choice(
1038
+ seq($.value_use, ":", choice($.type, $.function_type)),
1039
+ $.value_use,
1040
+ $.type,
1041
+ $.function_type,
1042
+ ),
1043
+ _type_or_func_type: ($) => choice($.type, $.function_type),
1044
+ type_list_attr_parens: ($) =>
1045
+ choice(
1046
+ $.type,
1047
+ $.function_type,
1048
+ seq(
1049
+ "(",
1050
+ $._type_or_func_type,
1051
+ optional($.attribute),
1052
+ repeat(seq(",", $._type_or_func_type, optional($.attribute))),
1053
+ ")",
1054
+ ),
1055
+ seq("(", ")"),
1056
+ ),
1057
+ variadic: ($) => token("..."),
501
1058
 
502
1059
  // =========================================================================
503
1060
  // Shared helpers
504
1061
  // =========================================================================
505
- _value_use_list_parens: $ => seq('(', optional($._value_use_list), ')'),
1062
+ _value_use_list_parens: ($) => seq("(", optional($._value_use_list), ")"),
506
1063
 
507
1064
  // Comment (standard BCPL)
508
- comment: $ => token(seq('//', /.*/)),
509
- }
1065
+ comment: ($) => token(seq("//", /.*/)),
1066
+ _dense_keyword: ($) => token(prec(1, "dense")),
1067
+ _sparse_keyword: ($) => token(prec(1, "sparse")),
1068
+ _complex_label_start: ($) => token(prec(2, /complex:/)),
1069
+ _complex_type_start: ($) => token(prec(1, /complex</)),
1070
+ },
510
1071
  });