@acristoffers/tree-sitter-matlab 1.2.4 → 1.2.13

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/README.md CHANGED
@@ -60,38 +60,40 @@ Given the existence of external method definition, maybe that is even the
60
60
  correct thing to do, since we don't know if the current file is inside a
61
61
  special class folder.
62
62
 
63
- # Known problems
64
-
65
- Newlines, just like whitespaces, are mostly ignored. In the case of spaces, it
66
- allows `abs( a )` and `abs(a)` to be described by the same, simple rule. In the
67
- case of newlines, it allows many multiline constructs (like, `if`, `while`,
68
- `function`) to be expressed the same way.
63
+ # Installation
69
64
 
70
- This creates the undesired side-effect that some constructs, which are not
71
- accepted by MATLAB, are correctly parsed, like:
65
+ This parser is available in the following editors:
72
66
 
73
- ```matlab
74
- function (
75
- a
76
- )
77
- end
78
- ```
67
+ | Editor | Plugin | Highlights | Folds | Indents | Code Format | Injections | Locals |
68
+ | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
69
+ | Emacs | [Emacs-MATLAB-Mode] | ✔ | ✘ | ✔ | ✔ | ✔ | ✘ |
70
+ | Helix | Builtin | ✔ | ✘ | ✔ | ✘ | ✘ | ✘ |
71
+ | NeoVim | [nvim-treesitter] | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ |
79
72
 
80
- This, however, is hard to fix. The assumption that newlines are ignored by
81
- default is all over the grammar and changing it requires making changes to too
82
- many rules, which also make them all more complex and fragile. Therefore, this
83
- change won't be made.
73
+ The columns have the following meaning:
84
74
 
85
- # Installation
75
+ - *Highlights*: supports syntax highlight
76
+ - *Folds*: supports code folding
77
+ - *Indents*: supports code indenting, which adjusts the leftmost whitespace on each line.
78
+ - *Code Format*: indent includes code formatting that standardizes the spacing of language elements
79
+ within code lines, aligns matrix columns, adds missing commas within cells and matrices, etc.
80
+ - *Injections*: supports embedding the language into another language (i.e.: MATLAB code blocks inside
81
+ Markdown or [org-mode](https://orgmode.org/))
82
+ - *Locals*: supports identifying variables/functions/etc scope
86
83
 
87
- This parser is now the default for the following editors:
84
+ # Known issues
88
85
 
89
- - Emacs: Through the `tree-sitter-langs` package.
90
- - Helix: Builtin, now in master and will be available in the next release (whatever comes after 23.05).
91
- - Neovim: Through the `nvim-treesitter` plugin.
86
+ - There is a conflict between numbers and element-wise operators that will
87
+ cause a wrong parse if there is no space between the number and the operator.
88
+ For example, `1./a` will be interpreted as `1. / a` instead of the correct
89
+ `1 ./ a`. This problem does not happen if there is a space between the number
90
+ and the operator.
92
91
 
93
92
  # Screenshots
94
93
 
95
94
  ![First Screenshot](https://raw.githubusercontent.com/acristoffers/tree-sitter-matlab/screenshots/s1.png)
96
95
  ![Second Screenshot](https://raw.githubusercontent.com/acristoffers/tree-sitter-matlab/screenshots/s2.png)
97
96
  ![Third Screenshot](https://raw.githubusercontent.com/acristoffers/tree-sitter-matlab/screenshots/s3.png)
97
+
98
+ [Emacs-MATLAB-Mode]: https://github.com/mathworks/Emacs-MATLAB-Mode
99
+ [nvim-treesitter]: https://github.com/nvim-treesitter/nvim-treesitter
package/grammar.js CHANGED
@@ -44,6 +44,8 @@ module.exports = grammar({
44
44
  [$._index_row, $.row],
45
45
  [$.function_call, $._function_call_with_keywords],
46
46
  [$.block, $._functionless_block],
47
+ [$.function_definition, $._function_definition_with_end],
48
+ [$._function_definition_with_end],
47
49
  ],
48
50
 
49
51
  externals: ($) => [
@@ -71,9 +73,12 @@ module.exports = grammar({
71
73
 
72
74
  rules: {
73
75
  source_file: ($) =>
74
- choice(
75
- optional(seq($._block, repeat($.function_definition))),
76
- repeat1($.function_definition),
76
+ seq(
77
+ repeat($._end_of_line),
78
+ choice(
79
+ optional(seq($._block, repeat($.function_definition))),
80
+ repeat1($.function_definition),
81
+ ),
77
82
  ),
78
83
 
79
84
  _block: ($) =>
@@ -235,6 +240,7 @@ module.exports = grammar({
235
240
  $.postfix_operator,
236
241
  $.string,
237
242
  $.unary_operator,
243
+ $.not_operator,
238
244
  ),
239
245
  ')',
240
246
  ),
@@ -261,7 +267,22 @@ module.exports = grammar({
261
267
  ),
262
268
  ),
263
269
 
264
- not_operator: ($) => prec(PREC.not, seq('~', $._expression)),
270
+ not_operator: ($) => prec(PREC.not, seq('~', choice(
271
+ $.cell,
272
+ $.function_call,
273
+ $.handle_operator,
274
+ $.identifier,
275
+ $.matrix,
276
+ $.metaclass_operator,
277
+ $.not_operator,
278
+ $.number,
279
+ $.parenthesis,
280
+ $.postfix_operator,
281
+ $.range,
282
+ $.string,
283
+ $.unary_operator,
284
+ $.field_expression,
285
+ ))),
265
286
 
266
287
  metaclass_operator: ($) => prec.left(seq('?', seq($.identifier, repeat(seq('.', $.identifier))))),
267
288
 
@@ -344,15 +365,15 @@ module.exports = grammar({
344
365
  matrix: ($) =>
345
366
  seq(
346
367
  '[',
347
- repeat("\n"),
348
- optional(seq($.row, repeat(seq(choice(';', /[\r\n]/), optional($.row))))),
368
+ repeat(choice(/[,]*;[ ,;]*/, /[\r\n]/)),
369
+ optional(seq($.row, repeat(seq(choice(/[,]*;[ ,;]*/, /[\r\n]/), optional($.row))))),
349
370
  ']',
350
371
  ),
351
372
  cell: ($) =>
352
373
  seq(
353
374
  '{',
354
- repeat("\n"),
355
- optional(seq($.row, repeat(seq(choice(';', /[\r\n]/), optional($.row))))),
375
+ repeat(choice(/[,]*;[ ,;]*/, /[\r\n]/)),
376
+ optional(seq($.row, repeat(seq(choice(/[,]*;[ ,;]*/, /[\r\n]/), optional($.row))))),
356
377
  '}',
357
378
  ),
358
379
 
@@ -461,7 +482,7 @@ module.exports = grammar({
461
482
  alias($._index_unary_operator, $.unary_operator),
462
483
  ),
463
484
  ),
464
- choice(".'", "'"),
485
+ choice(alias($._transpose, "'"), alias($._ctranspose, ".'")),
465
486
  ),
466
487
  ),
467
488
  _index_row: ($) =>
@@ -506,14 +527,20 @@ module.exports = grammar({
506
527
  ),
507
528
  ),
508
529
  _index_parenthesis: ($) => seq('(', $._index_expression, ')'),
530
+ // _index_expression is intentionally a superset of _expression to avoid
531
+ // conflicts like obj([1;end]) where the parser would otherwise reduce to
532
+ // a non-index matrix/row too early.
509
533
  _index_expression: ($) =>
510
534
  choice(
511
535
  alias($._index_boolean_operator, $.boolean_operator),
512
536
  $.field_expression,
513
537
  $.function_call,
538
+ $.handle_operator,
514
539
  $.identifier,
515
540
  $.cell,
541
+ $.lambda,
516
542
  alias($._index_matrix, $.matrix),
543
+ $.metaclass_operator,
517
544
  alias($._index_not_operator, $.not_operator),
518
545
  $.number,
519
546
  alias($._index_comparison_operator, $.comparison_operator),
@@ -569,7 +596,7 @@ module.exports = grammar({
569
596
  ),
570
597
  );
571
598
  },
572
- _index_argument: ($) => choice($.spread_operator, choice(prec.dynamic(1, $._index_expression), prec.dynamic(-1, $._expression))),
599
+ _index_argument: ($) => choice($.spread_operator, $._index_expression),
573
600
  _index_arguments: ($) => commaSep1(field('argument', $._index_argument)),
574
601
 
575
602
  arguments: ($) =>
@@ -705,7 +732,7 @@ module.exports = grammar({
705
732
  ),
706
733
 
707
734
  iterator: ($) => seq($.identifier, '=', $._expression),
708
- parfor_options: ($) => choice($.number, $.identifier, $.function_call, $.string),
735
+ parfor_options: ($) => choice($.number, $.identifier, $.field_expression, $.function_call, $.string),
709
736
  for_statement: ($) =>
710
737
  choice(
711
738
  seq(
@@ -786,7 +813,7 @@ module.exports = grammar({
786
813
  'arguments',
787
814
  optional(alias($._argument_attributes, $.attributes)),
788
815
  repeat1($._end_of_line),
789
- repeat(choice($.property, seq($.class_property, repeat1($._end_of_line)))),
816
+ repeat(seq(choice($.property, $.class_property), repeat1($._end_of_line))),
790
817
  'end',
791
818
  optional($._end_of_line),
792
819
  )),
@@ -796,36 +823,39 @@ module.exports = grammar({
796
823
  function_arguments: ($) =>
797
824
  seq('(', field('arguments', optional($._lambda_arguments)), ')'),
798
825
  function_definition: ($) =>
799
- prec.right(seq(
826
+ prec.dynamic(0, seq(
800
827
  'function',
801
828
  optional($.function_output),
802
829
  optional(choice('get.', 'set.')),
803
830
  field('name', choice($.identifier, $.property_name, alias($.end_keyword, $.identifier))),
804
831
  optional($.function_arguments),
805
832
  $._end_of_line,
806
- repeat($.arguments_statement),
807
- repeat($.comment),
808
- repeat($._end_of_line),
833
+ repeat(seq(repeat(choice($.comment, $._end_of_line)), $.arguments_statement)),
834
+ repeat(choice($.comment, $._end_of_line)),
809
835
  optional(alias($._functionless_block, $.block)),
810
836
  optional(seq(choice('end', 'endfunction'), optional(';'))),
811
837
  )),
812
838
  _function_definition_with_end: ($) =>
813
- prec.right(seq(
839
+ prec.dynamic(1, seq(
814
840
  'function',
815
841
  optional($.function_output),
816
842
  optional(choice('get.', 'set.')),
817
843
  field('name', choice($.identifier, $.property_name, alias($.end_keyword, $.identifier))),
818
844
  optional($.function_arguments),
819
- $._end_of_line,
820
- repeat($.arguments_statement),
821
- repeat($.comment),
822
- repeat($._end_of_line),
823
- optional($.block),
845
+ optional(
846
+ seq(
847
+ $._end_of_line,
848
+ repeat(seq(repeat(choice($.comment, $._end_of_line)), $.arguments_statement)),
849
+ repeat(choice($.comment, $._end_of_line)),
850
+ optional($.block),
851
+ )
852
+ ),
824
853
  choice('end', 'endfunction'),
825
854
  optional(';'),
826
855
  )),
827
856
 
828
- attribute: ($) => seq($.identifier, optional(seq('=', $._expression))),
857
+ _negated_attribute: ($) => seq("~", $.identifier),
858
+ attribute: ($) => choice(alias($._negated_attribute, $.not_operator), seq($.identifier, optional(seq('=', $._expression)))),
829
859
  attributes: ($) =>
830
860
  seq('(', $.attribute, repeat(seq(',', $.attribute)), ')'),
831
861
  superclasses: ($) =>
@@ -837,46 +867,44 @@ module.exports = grammar({
837
867
  default_value: ($) => seq('=', $._expression),
838
868
  property_name: ($) =>
839
869
  prec.right(
840
- prec.dynamic(
841
- -1,
842
- seq(
843
- $.identifier,
844
- repeat(seq('.', $.identifier)),
845
- optional(seq('.', '*')),
846
- ),
870
+ -1,
871
+ seq(
872
+ $.identifier,
873
+ repeat(seq('.', $.identifier)),
874
+ optional(seq('.', '*')),
847
875
  ),
848
876
  ),
849
877
  property: ($) =>
850
- choice(
851
- seq(
852
- field(
853
- 'name',
854
- choice($.identifier, $.property_name, $.ignored_argument),
878
+ prec.right(
879
+ choice(
880
+ seq(
881
+ field(
882
+ 'name',
883
+ choice($.identifier, $.property_name, $.ignored_argument),
884
+ ),
885
+ optional($.dimensions),
886
+ optional(choice($.identifier, $.property_name)),
887
+ optional($.validation_functions),
888
+ optional($.default_value),
855
889
  ),
856
- optional($.dimensions),
857
- optional(choice($.identifier, $.property_name)),
858
- optional($.validation_functions),
859
- optional($.default_value),
860
- repeat1($._end_of_line),
890
+ seq(
891
+ field(
892
+ 'name',
893
+ choice($.identifier, $.property_name, $.ignored_argument),
894
+ ),
895
+ '@',
896
+ $.identifier,
897
+ alias(optional(choice('vector', 'matrix', 'scalar')), $.identifier),
898
+ optional($.default_value),
899
+ )
861
900
  ),
862
- seq(
863
- field(
864
- 'name',
865
- choice($.identifier, $.property_name, $.ignored_argument),
866
- ),
867
- '@',
868
- $.identifier,
869
- alias(optional(choice('vector', 'matrix', 'scalar')), $.identifier),
870
- optional($.default_value),
871
- repeat1($._end_of_line),
872
- )
873
901
  ),
874
902
  properties: ($) =>
875
903
  seq(
876
904
  'properties',
877
905
  optional($.attributes),
878
- repeat1($._end_of_line),
879
- repeat($.property),
906
+ $._end_of_line,
907
+ repeat(choice(seq($.property, $._end_of_line), $._end_of_line, $.comment)),
880
908
  'end',
881
909
  ),
882
910
  function_signature: ($) =>
@@ -890,10 +918,11 @@ module.exports = grammar({
890
918
  seq(
891
919
  'methods',
892
920
  optional($.attributes),
893
- repeat1($._end_of_line),
921
+ repeat($._end_of_line),
894
922
  repeat(
895
923
  seq(
896
924
  choice(
925
+ $.comment,
897
926
  alias(seq($.function_output, field('name', alias('end', $.identifier)), $.function_arguments), $.function_signature),
898
927
  $.function_signature,
899
928
  alias($._function_definition_with_end, $.function_definition)),
@@ -906,7 +935,7 @@ module.exports = grammar({
906
935
  'events',
907
936
  optional($.attributes),
908
937
  $._end_of_line,
909
- repeat(choice(seq($.identifier, $._end_of_line), $._end_of_line)),
938
+ repeat(choice(seq($.identifier, $._end_of_line), $._end_of_line, $.comment)),
910
939
  'end',
911
940
  ),
912
941
  enum: ($) =>
@@ -916,7 +945,7 @@ module.exports = grammar({
916
945
  'enumeration',
917
946
  optional($.attributes),
918
947
  $._end_of_line,
919
- repeat(choice(seq($.enum, $._end_of_line), $._end_of_line)),
948
+ repeat(choice(seq($.enum, $._end_of_line), $._end_of_line, $.comment)),
920
949
  'end',
921
950
  ),
922
951
  class_definition: ($) =>
@@ -926,7 +955,7 @@ module.exports = grammar({
926
955
  field('name', $.identifier),
927
956
  optional($.superclasses),
928
957
  $._end_of_line,
929
- repeat(choice($.properties, $.methods, $.events, $.enumeration, ';')),
958
+ repeat(choice($.properties, $.methods, $.events, $.enumeration, $._end_of_line, $.comment)),
930
959
  'end',
931
960
  ),
932
961
 
@@ -957,8 +986,8 @@ module.exports = grammar({
957
986
 
958
987
  number: ($) => choice(
959
988
  /(\d+|\d+\.\d*|\.\d+)([eEdD][+-]?\d+)?[ij]?/,
960
- /0[xX][\dA-Fa-f]+([su](8|16|32|64))?/,
961
- /0[bB][01]+([su](8|16|32|64))?/
989
+ /0[xX][\dA-Fa-f]+([suSU](8|16|32|64))?/,
990
+ /0[bB][01]+([suSU](8|16|32|64))?/
962
991
  ),
963
992
 
964
993
  end_keyword: ($) => 'end',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acristoffers/tree-sitter-matlab",
3
- "version": "1.2.4",
3
+ "version": "1.2.13",
4
4
  "description": "MATLAB tree-sitter parser",
5
5
  "keywords": [
6
6
  "incremental",