aboutsummaryrefslogtreecommitdiff
path: root/vendor/tree-sitter-zig/grammar.js
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tree-sitter-zig/grammar.js')
-rw-r--r--vendor/tree-sitter-zig/grammar.js898
1 files changed, 898 insertions, 0 deletions
diff --git a/vendor/tree-sitter-zig/grammar.js b/vendor/tree-sitter-zig/grammar.js
new file mode 100644
index 0000000..e167748
--- /dev/null
+++ b/vendor/tree-sitter-zig/grammar.js
@@ -0,0 +1,898 @@
1/**
2 * @file Zig grammar for tree-sitter
3 * @author Amaan Qureshi <amaanq12@gmail.com>
4 * @license MIT
5 */
6
7/// <reference types="tree-sitter-cli/dsl" />
8// @ts-check
9
10const PREC = {
11 PAREN_DECLARATOR: -10,
12 CONDITIONAL: -1,
13 DEFAULT: 0,
14 LOGICAL_OR: 1,
15 LOGICAL_AND: 2,
16 EQUAL: 3,
17 BITWISE: 4,
18 SHIFT: 5,
19 ADD: 6,
20 MULTIPLY: 7,
21 UNARY: 8,
22 STRUCT: 9,
23 MEMBER: 10,
24};
25
26const builtinTypes = [
27 'bool',
28 'f16',
29 'f32',
30 'f64',
31 'f128',
32 'void',
33 'type',
34 'anyerror',
35 'anyopaque',
36 'anytype',
37 'noreturn',
38 'isize',
39 'usize',
40 'comptime_int',
41 'comptime_float',
42 'c_short',
43 'c_ushort',
44 'c_int',
45 'c_uint',
46 'c_long',
47 'c_ulong',
48 'c_longlong',
49 'c_ulonglong',
50 'c_longdouble',
51 /(i|u)[1-9][0-9]*/,
52];
53
54module.exports = grammar({
55 name: 'zig',
56
57 conflicts: $ => [
58 [$.for_expression],
59 [$.while_expression],
60
61 [$.expression, $._function_prototype],
62 [$.expression, $.if_type_expression],
63
64 [$.comptime_type_expression, $.expression],
65 [$.comptime_type_expression, $.parameter],
66 ],
67
68 extras: $ => [
69 $.comment,
70 /\s/,
71 ],
72
73 inline: $ => [
74 $._reserved_identifier,
75 ],
76
77 precedences: $ => [
78 [$.container_field, $.type_expression],
79 ],
80
81 supertypes: $ => [
82 $.statement,
83 $.expression,
84 $.type_expression,
85 $.primary_type_expression,
86 ],
87
88 word: $ => $._identifier,
89
90 rules: {
91 source_file: $ => optional($._container_members),
92
93 _container_members: $ => choice(
94 seq(
95 repeat1(choice(
96 $.test_declaration,
97 $.comptime_declaration,
98 $.variable_declaration,
99 $.function_declaration,
100 $.using_namespace_declaration,
101 seq($.container_field, ','),
102 )),
103 optional($.container_field),
104 ),
105 $.container_field,
106 ),
107
108 test_declaration: $ => seq(
109 optional('pub'),
110 'test',
111 optional(choice($.string, $.identifier)),
112 $.block,
113 ),
114
115 comptime_declaration: $ => prec(1, seq(
116 optional('pub'),
117 'comptime',
118 $.block,
119 )),
120
121 container_field: $ => prec.right(prec.dynamic(1, seq(
122 optional('comptime'),
123 choice(
124 seq(
125 field('name', choice($.identifier, $._reserved_identifier, alias($.builtin_type, $.identifier))),
126 ':',
127 field('type', choice($.primary_type_expression, $.if_type_expression, $.comptime_type_expression)),
128 ),
129 field('name', choice($.primary_type_expression, $.if_type_expression, $.comptime_type_expression)),
130 ),
131 optional($.byte_alignment),
132 optional(seq('=', $.expression)),
133 ))),
134
135 variable_declaration: $ => seq(
136 optional('pub'),
137 optional(choice(
138 'export',
139 seq('extern', optional($.string)),
140 )),
141 optional('threadlocal'),
142 $._variable_declaration_header,
143 optional(seq('=', $.expression)),
144 ';',
145 ),
146
147 _variable_declaration_expression_statement: $ => choice(
148 seq(
149 $._variable_declaration_header,
150 repeat(prec(1, seq(',', choice($._variable_declaration_header, $.expression)))),
151 '=',
152 $.expression,
153 ';',
154 ),
155 seq(
156 $.expression,
157 choice(
158 seq(
159 choice(
160 '=', '*=', '*%=', '*|=', '/=', '%=',
161 '+=', '+%=', '+|=', '-=', '-%=', '-|=',
162 '<<=', '<<|=', '>>=', '&=', '^=', '|=',
163 ),
164 $.expression,
165 ),
166 seq(
167 repeat1(prec(1, seq(',', choice($._variable_declaration_header, $.expression)))),
168 '=',
169 $.expression,
170 ),
171 ),
172 ';',
173 ),
174 ),
175
176 _variable_declaration_header: $ => prec(1, seq(
177 choice('const', 'var'),
178 $.identifier,
179 optional(seq(
180 ':',
181 field('type', choice($.type_expression, $.if_type_expression, $.comptime_type_expression)),
182 )),
183 optional($.byte_alignment),
184 optional($.address_space),
185 optional($.link_section),
186 )),
187
188 function_declaration: $ => seq(
189 optional('pub'),
190 optional(choice(
191 'export',
192 seq('extern', optional($.string)),
193 'inline',
194 'noinline',
195 )),
196 $._function_prototype,
197 choice(
198 ';',
199 field('body', $.block),
200 ),
201 ),
202
203 _function_prototype: $ => seq(
204 'fn',
205 optional(field('name', $.identifier)),
206 $.parameters,
207 optional($.byte_alignment),
208 optional($.address_space),
209 optional($.link_section),
210 optional($.calling_convention),
211 field('type', choice($.type_expression, $.if_type_expression, $.comptime_type_expression)),
212 ),
213
214 parameters: $ => seq('(', optionalCommaSep($.parameter), ')'),
215
216 parameter: $ => choice(
217 seq(
218 optional(choice('noalias', 'comptime')),
219 optional(seq(
220 field('name', choice($.identifier, alias($.builtin_type, $.identifier))),
221 ':',
222 )),
223 field('type', choice($.type_expression, $.if_type_expression, $.comptime_type_expression)),
224 ),
225 '...',
226 ),
227
228 using_namespace_declaration: $ => seq(
229 optional('pub'),
230 'usingnamespace',
231 $.expression,
232 ';',
233 ),
234
235 block: $ => seq(
236 '{',
237 repeat($.statement),
238 '}',
239 ),
240
241 struct_declaration: $ => seq(
242 optional(choice('extern', 'packed')),
243 'struct',
244 optional(seq('(', $.expression, ')')),
245 '{',
246 $._container_members,
247 '}',
248 ),
249
250 opaque_declaration: $ => seq(
251 optional(choice('extern', 'packed')),
252 'opaque',
253 '{',
254 $._container_members,
255 '}',
256 ),
257
258 enum_declaration: $ => seq(
259 optional(choice('extern', 'packed')),
260 'enum',
261 optional(seq('(', $.expression, ')')),
262 '{',
263 $._container_members,
264 '}',
265 ),
266
267 union_declaration: $ => seq(
268 optional(choice('extern', 'packed')),
269 'union',
270 optional(seq(
271 '(',
272 choice(
273 seq('enum', optional(seq('(', $.expression, ')'))),
274 $.expression,
275 ),
276 ')',
277 )),
278 '{',
279 $._container_members,
280 '}',
281 ),
282
283 error_set_declaration: $ => seq(
284 'error',
285 '{',
286 optionalCommaSep($.identifier),
287 '}',
288 ),
289
290 statement: $ => choice(
291 $.comptime_statement,
292 $.nosuspend_statement,
293 $.suspend_statement,
294 $.defer_statement,
295 $.errdefer_statement,
296 $.expression_statement,
297 alias($._variable_declaration_expression_statement, $.variable_declaration),
298 $.if_statement,
299 $.for_statement,
300 $.while_statement,
301 $.labeled_statement,
302 prec(1, $.switch_expression),
303 ),
304
305 comptime_statement: $ => seq(
306 'comptime',
307 choice(
308 $._block_expr_statement,
309 alias($._variable_declaration_expression_statement, $.variable_declaration),
310 ),
311 ),
312
313 nosuspend_statement: $ => seq('nosuspend', $._block_expr_statement),
314
315 suspend_statement: $ => seq('suspend', $._block_expr_statement),
316
317 defer_statement: $ => seq('defer', $._block_expr_statement),
318
319 errdefer_statement: $ => seq('errdefer', optional($.payload), $._block_expr_statement),
320
321 _block_expr_statement: $ => prec(1, choice(
322 seq(optional($.block_label), $.block),
323 $.expression_statement,
324 )),
325
326 block_expression: $ => prec(1, seq(optional($.block_label), $.block)),
327
328 labeled_statement: $ => prec(1, seq(
329 optional($.block_label),
330 choice($.block, $.for_statement, $.while_statement),
331 )),
332
333 expression_statement: $ => seq($.expression, ';'),
334
335 if_statement: $ => seq(
336 $._if_prefix,
337 $._conditional_body,
338 ),
339
340 _if_prefix: $ => seq(
341 'if',
342 '(',
343 field('condition', $.expression),
344 ')',
345 optional($.payload),
346 ),
347
348 else_clause: $ => seq(
349 'else',
350 optional($.payload),
351 field('alternative', $.statement),
352 ),
353
354 for_statement: $ => seq(
355 optional('inline'),
356 $._for_prefix,
357 $._conditional_body,
358 ),
359
360 _for_prefix: $ => seq(
361 'for',
362 '(',
363 optionalCommaSep(seq(
364 $.expression,
365 optional(seq('..', $.expression)),
366 )),
367 ')',
368 $.payload,
369 ),
370
371 while_statement: $ => seq(
372 optional('inline'),
373 $._while_prefix,
374 $._conditional_body,
375 ),
376
377 _while_prefix: $ => seq(
378 'while',
379 '(',
380 field('condition', $.expression),
381 ')',
382 optional($.payload),
383 optional(seq(':', '(', $.expression, ')')),
384 ),
385
386 _conditional_body: $ => choice(
387 seq(
388 field('body', $.block_expression),
389 optional($.else_clause),
390 ),
391 seq(
392 field('body', $.expression),
393 choice(';', $.else_clause),
394 ),
395 ),
396
397 payload: $ => seq('|', optionalCommaSep1(seq(optional('*'), $.identifier)), '|'),
398
399 byte_alignment: $ => seq('align', '(', $.expression, ')'),
400
401 address_space: $ => seq('addrspace', '(', $.expression, ')'),
402
403 link_section: $ => seq('linksection', '(', $.expression, ')'),
404
405 calling_convention: $ => seq('callconv', '(', $.expression, ')'),
406
407 expression: $ => prec.right(choice(
408 $.asm_expression,
409 $.if_expression,
410 $.for_expression,
411 $.while_expression,
412 $.assignment_expression,
413 $.unary_expression,
414 $.binary_expression,
415 $.comptime_expression,
416 $.async_expression,
417 $.await_expression,
418 $.nosuspend_expression,
419 $.continue_expression,
420 $.resume_expression,
421 $.return_expression,
422 $.break_expression,
423 $.try_expression,
424 $.catch_expression,
425 $.type_expression,
426 $.block,
427 )),
428
429 asm_expression: $ => seq(
430 'asm',
431 optional('volatile'),
432 '(',
433 $.expression,
434 optional($.asm_output),
435 ')',
436 ),
437 asm_output: $ => seq(':', optionalCommaSep($.asm_output_item), optional($.asm_input)),
438 asm_output_item: $ => seq(
439 '[',
440 $.identifier,
441 ']',
442 choice($.string, $.multiline_string),
443 '(',
444 choice(seq('->', $.type_expression), $.identifier),
445 ')',
446 ),
447 asm_input: $ => seq(':', optionalCommaSep($.asm_input_item), optional($.asm_clobbers)),
448 asm_input_item: $ => seq(
449 '[',
450 $.identifier,
451 ']',
452 choice($.string, $.multiline_string),
453 '(',
454 $.expression,
455 ')',
456 ),
457 asm_clobbers: $ => seq(':', optionalCommaSep(choice($.string, $.multiline_string))),
458
459 if_expression: $ => prec.right(seq(
460 $._if_prefix,
461 $.expression,
462 optional(seq('else', optional($.payload), $.expression)),
463 )),
464
465 for_expression: $ => prec.right(seq(
466 optional($.block_label),
467 optional('inline'),
468 $._for_prefix,
469 $.expression,
470 optional(seq('else', $.expression)),
471 )),
472
473 while_expression: $ => prec.right(seq(
474 optional($.block_label),
475 optional('inline'),
476 $._while_prefix,
477 $.expression,
478 optional(seq('else', optional($.payload), $.expression)),
479 )),
480
481 assignment_expression: $ => prec.right(seq(
482 field('left', $.expression),
483 field('operator', choice(
484 '=', '*=', '*%=', '*|=', '/=', '%=',
485 '+=', '+%=', '+|=', '-=', '-%=', '-|=',
486 '<<=', '<<|=', '>>=', '&=', '^=', '|=',
487 )),
488 field('right', $.expression),
489 )),
490
491 unary_expression: $ => prec.left(PREC.UNARY, seq(
492 field('operator', choice('!', '~', '-', '-%', '&')),
493 field('argument', $.expression),
494 )),
495
496 binary_expression: $ => {
497 const table = [
498 ['or', PREC.LOGICAL_OR],
499 ['and', PREC.LOGICAL_AND],
500 ['==', PREC.EQUAL],
501 ['!=', PREC.EQUAL],
502 ['>', PREC.EQUAL],
503 ['>=', PREC.EQUAL],
504 ['<=', PREC.EQUAL],
505 ['<', PREC.EQUAL],
506 ['&', PREC.BITWISE],
507 ['^', PREC.BITWISE],
508 ['|', PREC.BITWISE],
509 ['orelse', PREC.BITWISE],
510 ['<<', PREC.SHIFT],
511 ['>>', PREC.SHIFT],
512 ['<<|', PREC.SHIFT],
513 ['+', PREC.ADD],
514 ['-', PREC.ADD],
515 ['++', PREC.ADD],
516 ['+%', PREC.ADD],
517 ['-%', PREC.ADD],
518 ['+|', PREC.ADD],
519 ['-|', PREC.ADD],
520 ['*', PREC.MULTIPLY],
521 ['/', PREC.MULTIPLY],
522 ['%', PREC.MULTIPLY],
523 ['**', PREC.MULTIPLY],
524 ['*%', PREC.MULTIPLY],
525 ['*|', PREC.MULTIPLY],
526 ['||', PREC.MULTIPLY],
527 ];
528
529 return choice(...table.map(([operator, precedence]) => {
530 return prec.left(precedence, seq(
531 field('left', $.expression),
532 // @ts-ignore
533 field('operator', operator),
534 field('right', $.expression),
535 ));
536 }));
537 },
538
539 comptime_expression: $ => prec.right(seq('comptime', $.expression)),
540
541 async_expression: $ => prec.right(seq('async', $.expression)),
542
543 await_expression: $ => prec.right(seq('await', $.expression)),
544
545 nosuspend_expression: $ => prec.right(seq('nosuspend', $.expression)),
546
547 continue_expression: $ => prec.right(seq(
548 'continue',
549 optional($.break_label),
550 optional($.expression),
551 )),
552
553 resume_expression: $ => prec.right(seq('resume', $.expression)),
554
555 return_expression: $ => prec.right(seq('return', optional($.expression))),
556
557 break_expression: $ => prec.right(seq(
558 'break',
559 optional($.break_label),
560 optional($.expression),
561 )),
562
563 try_expression: $ => prec.right(PREC.BITWISE, seq('try', $.expression)),
564
565 catch_expression: $ => prec.right(PREC.BITWISE, seq(
566 $.expression,
567 'catch',
568 optional($.payload),
569 $.expression,
570 )),
571
572 switch_expression: $ => seq(
573 optional($.block_label),
574 'switch',
575 '(', $.expression, ')',
576 '{',
577 optionalCommaSep($.switch_case),
578 '}',
579 ),
580 switch_case: $ => seq(
581 $._switch_case_exp,
582 '=>',
583 optional($.payload),
584 choice($.expression),
585 ),
586 _switch_case_exp: $ => seq(
587 optional('inline'),
588 choice(
589 optionalCommaSep1(seq($.expression, optional(seq('...', $.expression)))),
590 'else',
591 ),
592 ),
593
594 type_expression: $ => prec.right(choice(
595 $.anonymous_struct_initializer,
596 $.struct_initializer,
597 $.labeled_type_expression,
598 $.error_set_declaration,
599 $.parenthesized_expression,
600 $.primary_type_expression,
601 )),
602
603 primary_type_expression: $ => choice(
604 $.nullable_type,
605 $.anyframe_type,
606 $.slice_type,
607 $.pointer_type,
608 $.array_type,
609 $.error_union_type,
610 $.builtin_function,
611 $.character,
612 $.field_expression,
613 $.index_expression,
614 $.dereference_expression,
615 $.null_coercion_expression,
616 $.range_expression,
617 $.call_expression,
618 prec.right(alias($._function_prototype, $.function_signature)),
619 $.identifier,
620 $.float,
621 $.integer,
622 $.boolean,
623 $.error_type,
624 'anyframe',
625 'unreachable',
626 'undefined',
627 'null',
628 $.string,
629 $.multiline_string,
630 $.builtin_type,
631 $.struct_declaration,
632 $.opaque_declaration,
633 $.enum_declaration,
634 $.union_declaration,
635 $.switch_expression,
636 ),
637
638 nullable_type: $ => prec(1, seq(
639 '?',
640 choice($.type_expression, $.if_type_expression, $.comptime_type_expression),
641 )),
642
643 anyframe_type: $ => prec(1, seq(
644 'anyframe',
645 '->',
646 $.type_expression,
647 )),
648
649 slice_type: $ => prec.right(1, seq(
650 '[',
651 optional(seq(
652 ':',
653 field('sentinel', $.expression),
654 )),
655 ']',
656 repeat(choice(
657 $.byte_alignment,
658 $.address_space,
659 'const',
660 'volatile',
661 'allowzero',
662 )),
663 $.type_expression,
664 )),
665
666 pointer_type: $ => prec.right(1, seq(
667 choice(
668 '*',
669 seq(
670 '[',
671 '*',
672 optional(choice('c', seq(':', $.expression))),
673 ']',
674 ),
675 ),
676 repeat(choice(
677 $.address_space,
678 seq(
679 'align',
680 '(',
681 $.expression,
682 optional(seq(':', $.expression, ':', $.expression)),
683 ')',
684 ),
685 'const',
686 'volatile',
687 'allowzero',
688 )),
689 $.type_expression,
690 )),
691
692 array_type: $ => prec(1, seq(
693 '[',
694 $.expression,
695 optional(seq(':', $.expression)),
696 ']',
697 $.type_expression,
698 )),
699
700 error_union_type: $ => prec.right(2, seq(
701 optional(field('error', $.type_expression)),
702 '!',
703 field('ok', $.type_expression),
704 )),
705
706 field_expression: $ => prec(PREC.MEMBER, seq(
707 optional(field('object', $.expression)),
708 '.',
709 field('member', $.identifier),
710 )),
711
712 index_expression: $ => prec(PREC.MEMBER, seq(
713 field('object', $.expression),
714 '[',
715 field('index', $.expression),
716 optional(seq(':', field('sentinel', $.expression))),
717 ']',
718 )),
719
720 dereference_expression: $ => prec(PREC.MEMBER, seq($.expression, '.*')),
721
722 null_coercion_expression: $ => prec(PREC.MEMBER, seq($.expression, '.?')),
723
724 range_expression: $ => prec.right(PREC.MEMBER, seq(
725 field('left', $.expression),
726 '..',
727 optional(field('right', $.expression)),
728 )),
729
730 call_expression: $ => prec(PREC.MEMBER, seq(
731 field('function', $.expression),
732 field('arguments', $.arguments),
733 )),
734
735 anonymous_struct_initializer: $ => seq('.', $.initializer_list),
736
737 struct_initializer: $ => prec(-1, seq($.primary_type_expression, $.initializer_list)),
738
739 initializer_list: $ => seq(
740 '{',
741 choice(
742 optionalCommaSep($.field_initializer),
743 optionalCommaSep($.expression),
744 ),
745 '}',
746 ),
747
748 field_initializer: $ => seq(
749 '.',
750 $.identifier,
751 '=',
752 $.expression,
753 ),
754
755 labeled_type_expression: $ => seq($.block_label, $.block),
756
757 comptime_type_expression: $ => seq('comptime', $.type_expression),
758
759 if_type_expression: $ => prec.right(seq(
760 $._if_prefix,
761 $.type_expression,
762 optional(seq('else', optional($.payload), $.type_expression)),
763 )),
764
765 parenthesized_expression: $ => seq('(', $.expression, ')'),
766
767 block_label: $ => prec(-1, seq(
768 choice($.identifier, alias($.builtin_type, $.identifier)),
769 ':',
770 )),
771 break_label: $ => seq(':', $.identifier),
772
773 arguments: $ => seq('(', optionalCommaSep($.expression), ')'),
774
775 builtin_function: $ => seq(
776 $.builtin_identifier,
777 $.arguments,
778 ),
779
780 string: $ => seq(
781 '"',
782 repeat(choice(
783 alias(token.immediate(prec(1, /[^\\"\n]+/)), $.string_content),
784 $.escape_sequence,
785 )),
786 '"',
787 ),
788
789 multiline_string: _ => prec.right(repeat1(token(seq('\\\\', /[^\n]*/)))),
790
791 escape_sequence: _ => token(prec(1, seq(
792 '\\',
793 choice(
794 /[^xuU]/,
795 /\d{2,3}/,
796 /x[0-9a-fA-F]{2,}/,
797 /u\{[0-9a-fA-F]{1,6}\}/,
798 ),
799 ))),
800
801 character: $ => seq(
802 '\'',
803 choice(
804 alias(/[^'\n]/, $.character_content),
805 $.escape_sequence,
806 ),
807 '\'',
808 ),
809
810 integer: _ => {
811 const separator = '_';
812 const hex = /[0-9A-Fa-f]/;
813 const oct = /[0-7]/;
814 const bin = /[0-1]/;
815 const decimal = /[0-9]/;
816 const hexDigits = seq(repeat1(hex), repeat(seq(separator, repeat1(hex))));
817 const octDigits = seq(repeat1(oct), repeat(seq(separator, repeat1(oct))));
818 const binDigits = seq(repeat1(bin), repeat(seq(separator, repeat1(bin))));
819 const decimalDigits = seq(repeat1(decimal), repeat(seq(separator, repeat1(decimal))));
820
821 return token(choice(
822 seq('0x', hexDigits),
823 seq('0o', octDigits),
824 seq('0b', binDigits),
825 decimalDigits,
826 ));
827 },
828
829 float: _ => {
830 const separator = '_';
831 const hex = /[0-9A-Fa-f]/;
832 const decimal = /[0-9]/;
833 const hexDigits = seq(repeat1(hex), repeat(seq(separator, repeat1(hex))));
834 const decimalDigits = seq(repeat1(decimal), repeat(seq(separator, repeat1(decimal))));
835
836 return token(choice(
837 seq('0x', hexDigits, '.', hexDigits, optional(seq(/[pP][+-]?/, decimalDigits))),
838 seq(decimalDigits, '.', decimalDigits, optional(seq(/[eE][+-]?/, decimalDigits))),
839 seq('0x', hexDigits, /[pP][+-]?/, decimalDigits),
840 seq(decimalDigits, /[eE][+-]?/, decimalDigits),
841 ));
842 },
843
844 boolean: _ => choice('true', 'false'),
845
846 builtin_type: _ => choice(...builtinTypes),
847
848 error_type: $ => seq('error', '.', $.identifier),
849
850 builtin_identifier: _ => /@[A-Za-z_][A-Za-z0-9_]*/,
851
852 identifier: $ => choice($._identifier, seq('@', $.string)),
853 _identifier: _ => /[A-Za-z_][A-Za-z0-9_]*/,
854 _reserved_identifier: _ => choice(
855 'undefined',
856 'null',
857 'true',
858 'false',
859 ),
860
861 comment: _ => token(seq('//', /.*/)),
862 },
863});
864
865/**
866 * Creates a rule to match optionally match one or more of the rules
867 * separated by a comma and optionally ending with a comma
868 *
869 * @param {RuleOrLiteral} rule
870 *
871 * @returns {ChoiceRule}
872 */
873function optionalCommaSep(rule) {
874 return optional(optionalCommaSep1(rule));
875}
876
877/**
878 * Creates a rule to match one or more of the rules separated by a comma
879 * and optionally ending with a comma
880 *
881 * @param {RuleOrLiteral} rule
882 *
883 * @returns {SeqRule}
884 */
885function optionalCommaSep1(rule) {
886 return seq(commaSep1(rule), optional(','));
887}
888
889/**
890 * Creates a rule to match one or more of the rules separated by a comma
891 *
892 * @param {RuleOrLiteral} rule
893 *
894 * @returns {SeqRule}
895 */
896function commaSep1(rule) {
897 return seq(rule, repeat(seq(',', rule)));
898}