@felixtensor/tree-sitter-mlir 0.1.3 → 0.1.5

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
@@ -5,20 +5,45 @@ export default grammar({
5
5
  name: "mlir",
6
6
  extras: ($) => [/[\s\x00]/, $.comment],
7
7
  conflicts: ($) => [
8
+ // Core MLIR overlaps: shaped dimensions, aliases, pretty dialect payloads,
9
+ // value/type lists, and affine syntax share prefixes by design.
8
10
  [$._static_dim_list, $._static_dim_list],
9
- [$.dictionary_attribute, $.region],
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_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],
19
14
  [$._value_use_list, $._value_use_and_type],
20
15
  [$._type_list_no_parens, $._type_or_func_type],
21
16
  [$._type_list_parens, $._multi_dim_affine_expr_parens],
17
+
18
+ // Custom operation fallback overlaps: loose body syntax must preserve
19
+ // dialect keywords, dictionary-looking payloads, and loc-sensitive forms
20
+ // without enumerating every upstream dialect operation.
21
+ [$.custom_op_name, $.attribute_entry],
22
+ [$.array_literal, $._custom_body_array_keyword],
23
+ [$._custom_body_tensor_keyword, $.tensor_type],
24
+ [$._generic_custom_operation_with_location_attr_dict, $.custom_op_name],
25
+ [$._custom_body_dict_key, $.attribute_entry],
26
+ ],
27
+ inline: ($) => [
28
+ $._tier1_custom_operation,
29
+ $._tier2_custom_operation,
30
+ $._custom_body_reference_element,
31
+ $._custom_body_type_element,
32
+ $._custom_body_attribute_or_braced_element,
33
+ $._custom_body_dialect_marker,
34
+ $._custom_body_group,
35
+ $._custom_body_atom,
36
+ $._custom_body_literal_element,
37
+ $._custom_body_reserved_keyword,
38
+ $._custom_body_affine_keyword,
39
+ $._custom_body_brace_payload,
40
+ $._custom_body_punctuation,
41
+ $._custom_body_separator_punctuation,
42
+ $._custom_body_operator_punctuation,
43
+ $._pretty_dialect_structural_content,
44
+ $._pretty_dialect_value_content,
45
+ $._pretty_dialect_keyword_content,
46
+ $._pretty_dialect_punctuation_content,
22
47
  ],
23
48
 
24
49
  // Token-level precedence constants (higher wins the token race):
@@ -47,7 +72,17 @@ export default grammar({
47
72
  $.external_resources,
48
73
  ),
49
74
  external_resources: ($) =>
50
- seq("{-#", repeat($._pretty_dialect_item_contents), "#-}"),
75
+ seq("{-#", repeat($._external_resource_content), "#-}"),
76
+ _external_resource_content: ($) =>
77
+ choice(
78
+ $.string_literal,
79
+ // File metadata is YAML-like, not a dialect pretty body. Keep it loose
80
+ // so resource keys such as dense_resource_test_2xi32 are not split by
81
+ // dimension-list/type rules.
82
+ token(prec(-1, /[^#"\/]+/)),
83
+ "#",
84
+ "/",
85
+ ),
51
86
 
52
87
  // =========================================================================
53
88
  // Common syntax (lang-ref)
@@ -55,7 +90,7 @@ export default grammar({
55
90
  // decimal-literal ::= digit+
56
91
  // hexadecimal-literal ::= `0x` hex_digit+
57
92
  // float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
58
- // string-literal ::= `"` [^"\n\f\v\r]* `"`
93
+ // string-literal ::= `"` (char | escape-sequence | invalid-escape)* `"`
59
94
  // =========================================================================
60
95
  _digit: ($) => /[0-9]/,
61
96
  integer_literal: ($) => choice($._decimal_literal, $._hexadecimal_literal),
@@ -274,10 +309,18 @@ export default grammar({
274
309
  // Tier 2: _generic_custom_operation — all other dialect.op_name patterns
275
310
  // =========================================================================
276
311
  custom_operation: ($) =>
312
+ choice($._tier1_custom_operation, $._tier2_custom_operation),
313
+
314
+ _tier1_custom_operation: ($) =>
277
315
  choice(
278
316
  prec(2, $.func_operation),
279
317
  prec(2, $.module_operation),
280
318
  prec(2, $._affine_for_operation),
319
+ ),
320
+
321
+ _tier2_custom_operation: ($) =>
322
+ choice(
323
+ $._pdl_interp_record_match_operation,
281
324
  $._generic_custom_operation_with_location_attr_dict,
282
325
  $._generic_custom_operation,
283
326
  ),
@@ -350,6 +393,27 @@ export default grammar({
350
393
  ),
351
394
  ),
352
395
 
396
+ // These stay as specialized operation forms because `loc(...)` can be
397
+ // either custom body syntax or the operation-level trailing location.
398
+ _pdl_interp_record_match_operation: ($) =>
399
+ prec.dynamic(
400
+ -1,
401
+ prec.right(
402
+ seq(
403
+ field(
404
+ "name",
405
+ alias(
406
+ token(prec(20, "pdl_interp.record_match")),
407
+ $.custom_op_name,
408
+ ),
409
+ ),
410
+ repeat($._custom_body_element),
411
+ $._custom_body_location_list,
412
+ repeat($._custom_body_element),
413
+ ),
414
+ ),
415
+ ),
416
+
353
417
  // Tier 2: Generic custom operation — dialect.op_name + structural body
354
418
  // Negative dynamic precedence makes the parser prefer ending the body
355
419
  // and starting a new operation (with _op_result_list) over extending
@@ -419,48 +483,116 @@ export default grammar({
419
483
  _custom_body_element: ($) =>
420
484
  choice(
421
485
  $._custom_body_element_base,
486
+ // Kept out of _custom_body_element_base because nested delimiter bodies
487
+ // should still treat `>` as an angle-group boundary, not a loose marker.
422
488
  $._custom_body_successor_marker, // >^bb1 (WasmSSA if continuation)
423
489
  ),
424
490
 
425
491
  _custom_body_element_base: ($) =>
492
+ choice(
493
+ $._custom_body_reference_element,
494
+ $._custom_body_type_element,
495
+ $._custom_body_attribute_or_braced_element,
496
+ $._custom_body_dialect_marker,
497
+ $._custom_body_group,
498
+ $._custom_body_atom,
499
+ $._custom_body_punctuation,
500
+ ),
501
+
502
+ _custom_body_reference_element: ($) =>
426
503
  choice(
427
504
  $.value_use, // %foo, %0
428
505
  $.symbol_ref_id, // @sym, @"string"
429
506
  $.successor, // ^bb0, ^bb0(%arg : type)
430
- $._custom_body_complex_label, // complex: %value (IRDL operand label)
431
- prec(2, $.type), // !type, i32, memref<...>, etc.
507
+ ),
508
+
509
+ _custom_body_type_element: ($) =>
510
+ prec(2, $.type), // !type, i32, memref<...>, etc.
511
+
512
+ // Attribute includes dictionary_attribute, so keep it adjacent to the
513
+ // custom-body `{...}` payloads while preserving the public wrapper.
514
+ _custom_body_attribute_or_braced_element: ($) =>
515
+ choice(
432
516
  $.attribute, // #attr, {dict}, affine_map<...>
517
+ $._custom_body_brace_payload,
518
+ ),
519
+
520
+ _custom_body_brace_payload: ($) =>
521
+ choice(
433
522
  $._custom_body_tuple_group, // {(%v), (%w)}
434
523
  $.region, // { ... } (regions with operations)
435
524
  $._custom_body_value_group, // {%v : type, ...}
436
525
  $._custom_body_ssa_dict, // {"attr" = %value, ...} / options with SSA values
526
+ ),
527
+
528
+ _custom_body_dialect_marker: ($) =>
529
+ choice(
530
+ $._custom_body_arrow, // <- (OpenMP loop transform mapped-from marker)
531
+ $._custom_body_complex_label, // complex: %value (IRDL operand label)
532
+ $._custom_body_module_symbol_arg, // module(@sym) kernel attr
437
533
  $._custom_body_sparse_operand, // sparse(%idx : type)
534
+ ),
535
+
536
+ _custom_body_group: ($) =>
537
+ choice(
438
538
  $._custom_body_paren, // ( ... )
439
539
  $._custom_body_bracket, // [ ... ]
440
540
  $._custom_body_angle_group, // < ... >
541
+ ),
542
+
543
+ _custom_body_atom: ($) =>
544
+ choice(
545
+ $._custom_body_literal_element,
546
+ $._custom_body_reserved_keyword,
547
+ $.bare_id, // keywords: to, from, step, ins, outs, etc.
548
+ ),
549
+
550
+ _custom_body_literal_element: ($) =>
551
+ choice(
552
+ $.variadic, // custom assembly ellipsis marker
441
553
  $._literal, // 42, 3.14, "string", true, dense<...>
442
- "array", // property names may collide with array<...>
554
+ ),
555
+
556
+ _custom_body_reserved_keyword: ($) =>
557
+ choice(
558
+ $._custom_body_array_keyword, // property names may collide with array<...>
443
559
  "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 <- (...))
560
+ $._custom_body_tensor_keyword, // AMDGPU/NVGPU keyword may collide with tensor<...>
561
+ $._custom_body_affine_keyword, // inline affine keywords
562
+ ),
563
+
564
+ _custom_body_array_keyword: ($) => "array",
565
+ _custom_body_tensor_keyword: ($) => "tensor",
566
+ _custom_body_affine_keyword: ($) =>
567
+ choice("ceildiv", "floordiv", "mod"),
568
+
569
+ _custom_body_punctuation: ($) =>
570
+ choice(
571
+ $._custom_body_separator_punctuation,
572
+ $._custom_body_operator_punctuation,
573
+ ),
574
+
575
+ _custom_body_separator_punctuation: ($) =>
576
+ choice(
450
577
  ",",
451
578
  "=",
452
579
  ":",
453
580
  "->",
581
+ ),
582
+
583
+ _custom_body_operator_punctuation: ($) =>
584
+ choice(
454
585
  "*",
455
586
  "?",
456
587
  $.dimension_separator,
457
588
  "+",
458
- "-",
589
+ $._custom_body_minus_punctuation,
459
590
  "/",
460
591
  "&",
461
592
  "|",
462
593
  "~",
463
594
  ),
595
+ _custom_body_minus_punctuation: ($) => "-",
464
596
 
465
597
  _custom_body_paren: ($) =>
466
598
  seq("(", repeat($._nested_custom_body_element), ")"),
@@ -513,8 +645,12 @@ export default grammar({
513
645
  _custom_body_ssa_value_array: ($) =>
514
646
  seq("[", $.value_use, repeat(seq(",", $.value_use)), "]"),
515
647
  _custom_body_successor_marker: ($) => seq(">", $.successor),
648
+ _custom_body_module_symbol_arg: ($) =>
649
+ seq(token(prec(20, "module(")), $.symbol_ref_id, ")"),
516
650
  _custom_body_sparse_operand: ($) =>
517
651
  seq($._sparse_keyword, $._custom_body_paren),
652
+ _custom_body_location_list: ($) =>
653
+ seq(token("loc"), "(", "[", optional($._value_use_list), "]", ")"),
518
654
  _custom_body_angle_group: ($) =>
519
655
  seq("<", repeat($._nested_custom_body_element), ">"),
520
656
  // "Mapped-from" arrow used by OpenMP loop-transform ops, e.g.
@@ -526,7 +662,7 @@ export default grammar({
526
662
  // mis-lex negative payloads like `#smt.bv<-1>` as `<-` `1`. Keeping the
527
663
  // tokens separate leaves the lexer unchanged; GLR distinguishes the arrow
528
664
  // from `_custom_body_angle_group` (which requires a closing '>').
529
- _custom_body_arrow: ($) => seq("<", "-"),
665
+ _custom_body_arrow: ($) => prec(1, seq("<", "-")),
530
666
  // Only nested groups accept `trailing_location` as a body element.
531
667
  // At the top level it is omitted on purpose so the operation rule
532
668
  // captures a trailing `loc(...)` as the operation's location instead of
@@ -572,7 +708,8 @@ export default grammar({
572
708
  // region ::= `{` entry-block? block* `}`
573
709
  // entry-block ::= operation+
574
710
  // =========================================================================
575
- region: ($) => seq("{", optional($.entry_block), repeat($.block), "}"),
711
+ region: ($) =>
712
+ prec(1, seq("{", optional($.entry_block), repeat($.block), "}")),
576
713
  entry_block: ($) => repeat1($.operation),
577
714
 
578
715
  // =========================================================================
@@ -630,37 +767,48 @@ export default grammar({
630
767
  _pretty_dialect_item_contents: ($) =>
631
768
  prec.left(
632
769
  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
- "#",
770
+ $._pretty_dialect_structural_content,
771
+ $._pretty_dialect_value_content,
772
+ $._pretty_dialect_keyword_content,
773
+ $._pretty_dialect_punctuation_content,
661
774
  token(prec(-1, /[^<>]/)),
662
775
  ),
663
776
  ),
777
+ _pretty_dialect_structural_content: ($) =>
778
+ choice(
779
+ $.pretty_dialect_item_body,
780
+ $._pretty_dialect_bang_body_token,
781
+ $._pretty_dialect_body_attribute,
782
+ ),
783
+ _pretty_dialect_value_content: ($) =>
784
+ choice($.dialect_dim_list, $.type, prec(2, $.attribute), $._literal),
785
+ _pretty_dialect_keyword_content: ($) =>
786
+ choice(
787
+ $._dense_keyword,
788
+ $._sparse_keyword,
789
+ "array",
790
+ "vector",
791
+ "tensor",
792
+ "opaque",
793
+ $.bare_id,
794
+ ),
795
+ _pretty_dialect_punctuation_content: ($) =>
796
+ choice(
797
+ ",",
798
+ ":",
799
+ "=",
800
+ "->",
801
+ "(",
802
+ ")",
803
+ "[",
804
+ "]",
805
+ "{",
806
+ "}",
807
+ "*",
808
+ "?",
809
+ "@",
810
+ "#",
811
+ ),
664
812
  _pretty_dialect_bang_body_token: ($) =>
665
813
  token(prec(1, seq("!", /[^a-zA-Z_<>]/))),
666
814
  _pretty_dialect_body_attribute: ($) =>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@felixtensor/tree-sitter-mlir",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "MLIR grammar for tree-sitter",
5
5
  "type": "module",
6
6
  "repository": {
@@ -55,9 +55,10 @@
55
55
  "compile": "tree-sitter generate",
56
56
  "update-tests": "tree-sitter test --update",
57
57
  "test": "tree-sitter test",
58
+ "test:bench": "node --test test/*.test.mjs",
58
59
  "test:bindings": "node --test bindings/node/*_test.js",
59
- "test:examples": "tree-sitter parse --quiet --stat examples/**/*.mlir",
60
- "test:all": "npm run test && npm run test:examples",
60
+ "test:examples": "tree-sitter parse --quiet --stat \"examples/**/*.mlir\"",
61
+ "test:all": "npm run test && npm run test:bench && npm run test:examples",
61
62
  "bench": "node bench.mjs",
62
63
  "prebuildify": "prebuildify --napi --strip"
63
64
  },