@willbooster/tree-sitter-go 0.0.0-placeholder.0 → 1.0.0

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 ADDED
@@ -0,0 +1,983 @@
1
+ /**
2
+ * @file Go grammar for tree-sitter
3
+ * @author Max Brunsfeld <maxbrunsfeld@gmail.com>
4
+ * @author Amaan Qureshi <amaanq12@gmail.com>
5
+ * @license MIT
6
+ */
7
+
8
+ /// <reference types="tree-sitter-cli/dsl" />
9
+ // @ts-check
10
+
11
+ const PREC = {
12
+ primary: 7,
13
+ unary: 6,
14
+ multiplicative: 5,
15
+ additive: 4,
16
+ comparative: 3,
17
+ and: 2,
18
+ or: 1,
19
+ composite_literal: -1,
20
+ };
21
+
22
+ const multiplicativeOperators = ['*', '/', '%', '<<', '>>', '&', '&^'];
23
+ const additiveOperators = ['+', '-', '|', '^'];
24
+ const comparativeOperators = ['==', '!=', '<', '<=', '>', '>='];
25
+ const assignmentOperators = multiplicativeOperators.concat(additiveOperators).map(operator => operator + '=').concat('=');
26
+
27
+
28
+ const newline = /\n/;
29
+ const terminator = choice(newline, ';', '\0');
30
+
31
+ const hexDigit = /[0-9a-fA-F]/;
32
+ const octalDigit = /[0-7]/;
33
+ const decimalDigit = /[0-9]/;
34
+ const binaryDigit = /[01]/;
35
+
36
+ const hexDigits = seq(hexDigit, repeat(seq(optional('_'), hexDigit)));
37
+ const octalDigits = seq(octalDigit, repeat(seq(optional('_'), octalDigit)));
38
+ const decimalDigits = seq(decimalDigit, repeat(seq(optional('_'), decimalDigit)));
39
+ const binaryDigits = seq(binaryDigit, repeat(seq(optional('_'), binaryDigit)));
40
+
41
+ const hexLiteral = seq('0', choice('x', 'X'), optional('_'), hexDigits);
42
+ const octalLiteral = seq('0', optional(choice('o', 'O')), optional('_'), octalDigits);
43
+ const decimalLiteral = choice('0', seq(/[1-9]/, optional(seq(optional('_'), decimalDigits))));
44
+ const binaryLiteral = seq('0', choice('b', 'B'), optional('_'), binaryDigits);
45
+
46
+ const intLiteral = choice(binaryLiteral, decimalLiteral, octalLiteral, hexLiteral);
47
+
48
+ const decimalExponent = seq(choice('e', 'E'), optional(choice('+', '-')), decimalDigits);
49
+ const decimalFloatLiteral = choice(
50
+ seq(decimalDigits, '.', optional(decimalDigits), optional(decimalExponent)),
51
+ seq(decimalDigits, decimalExponent),
52
+ seq('.', decimalDigits, optional(decimalExponent)),
53
+ );
54
+
55
+ const hexExponent = seq(choice('p', 'P'), optional(choice('+', '-')), decimalDigits);
56
+ const hexMantissa = choice(
57
+ seq(optional('_'), hexDigits, '.', optional(hexDigits)),
58
+ seq(optional('_'), hexDigits),
59
+ seq('.', hexDigits),
60
+ );
61
+ const hexFloatLiteral = seq('0', choice('x', 'X'), hexMantissa, hexExponent);
62
+
63
+ const floatLiteral = choice(decimalFloatLiteral, hexFloatLiteral);
64
+
65
+ const imaginaryLiteral = seq(choice(decimalDigits, intLiteral, floatLiteral), 'i');
66
+
67
+ module.exports = grammar({
68
+ name: 'go',
69
+
70
+ extras: $ => [
71
+ $.comment,
72
+ /\s/,
73
+ ],
74
+
75
+ inline: $ => [
76
+ $._type,
77
+ $._type_identifier,
78
+ $._field_identifier,
79
+ $._package_identifier,
80
+ $._top_level_declaration,
81
+ $._string_literal,
82
+ $._interface_elem,
83
+ ],
84
+
85
+ word: $ => $.identifier,
86
+
87
+ conflicts: $ => [
88
+ [$._simple_type, $._expression],
89
+ [$._simple_type, $.generic_type, $._expression],
90
+ [$.qualified_type, $._expression],
91
+ [$.generic_type, $._simple_type],
92
+ [$.parameter_declaration, $._simple_type],
93
+ [$.type_parameter_declaration, $._simple_type, $._expression],
94
+ [$.type_parameter_declaration, $._expression],
95
+ [$.type_parameter_declaration, $._simple_type, $.generic_type, $._expression],
96
+ ],
97
+
98
+ reserved: {
99
+ global: $ => [
100
+ // https://go.dev/ref/spec#Keywords
101
+ 'break', 'default', 'func', 'interface', 'select',
102
+ 'case', 'defer', 'go', 'map', 'struct',
103
+ 'chan', 'else', 'goto', 'package', 'switch',
104
+ 'const', 'fallthrough', 'if', 'range', 'type',
105
+ 'continue', 'for', 'import', 'return', 'var',
106
+ ],
107
+ },
108
+
109
+ supertypes: $ => [
110
+ $._expression,
111
+ $._type,
112
+ $._simple_type,
113
+ $._statement,
114
+ $._simple_statement,
115
+ ],
116
+
117
+ rules: {
118
+ source_file: $ => seq(
119
+ repeat(choice(
120
+ // Unlike a Go compiler, we accept statements at top-level to enable
121
+ // parsing of partial code snippets in documentation (see #63).
122
+ seq($._statement, terminator),
123
+ seq($._top_level_declaration, terminator),
124
+ )),
125
+ optional($._top_level_declaration),
126
+ ),
127
+
128
+ _top_level_declaration: $ => choice(
129
+ $.package_clause,
130
+ $.function_declaration,
131
+ $.method_declaration,
132
+ $.import_declaration,
133
+ ),
134
+
135
+ package_clause: $ => seq(
136
+ 'package',
137
+ $._package_identifier,
138
+ ),
139
+
140
+ import_declaration: $ => seq(
141
+ 'import',
142
+ choice(
143
+ $.import_spec,
144
+ $.import_spec_list,
145
+ ),
146
+ ),
147
+
148
+ import_spec: $ => seq(
149
+ optional(field('name', choice(
150
+ $.dot,
151
+ $.blank_identifier,
152
+ $._package_identifier,
153
+ ))),
154
+ field('path', $._string_literal),
155
+ ),
156
+ dot: _ => '.',
157
+ blank_identifier: _ => '_',
158
+
159
+ import_spec_list: $ => seq(
160
+ '(',
161
+ optional(seq(
162
+ $.import_spec,
163
+ repeat(seq(terminator, $.import_spec)),
164
+ optional(terminator),
165
+ )),
166
+ ')',
167
+ ),
168
+
169
+ _declaration: $ => choice(
170
+ $.const_declaration,
171
+ $.type_declaration,
172
+ $.var_declaration,
173
+ ),
174
+
175
+ const_declaration: $ => seq(
176
+ 'const',
177
+ choice(
178
+ $.const_spec,
179
+ seq(
180
+ '(',
181
+ repeat(seq($.const_spec, terminator)),
182
+ ')',
183
+ ),
184
+ ),
185
+ ),
186
+
187
+ const_spec: $ => prec.left(seq(
188
+ field('name', commaSep1($.identifier)),
189
+ optional(seq(
190
+ optional(field('type', $._type)),
191
+ '=',
192
+ field('value', $.expression_list),
193
+ )),
194
+ )),
195
+
196
+ var_declaration: $ => seq(
197
+ 'var',
198
+ choice(
199
+ $.var_spec,
200
+ $.var_spec_list,
201
+ ),
202
+ ),
203
+
204
+ var_spec: $ => seq(
205
+ commaSep1(field('name', $.identifier)),
206
+ choice(
207
+ seq(
208
+ field('type', $._type),
209
+ optional(seq('=', field('value', $.expression_list))),
210
+ ),
211
+ seq('=', field('value', $.expression_list)),
212
+ ),
213
+ ),
214
+
215
+ var_spec_list: $ => seq(
216
+ '(',
217
+ repeat(seq($.var_spec, terminator)),
218
+ ')',
219
+ ),
220
+
221
+ function_declaration: $ => prec.right(1, seq(
222
+ 'func',
223
+ field('name', $.identifier),
224
+ field('type_parameters', optional($.type_parameter_list)),
225
+ field('parameters', $.parameter_list),
226
+ field('result', optional(choice($.parameter_list, $._simple_type))),
227
+ field('body', optional($.block)),
228
+ )),
229
+
230
+ method_declaration: $ => prec.right(1, seq(
231
+ 'func',
232
+ field('receiver', $.parameter_list),
233
+ field('name', $._field_identifier),
234
+ field('parameters', $.parameter_list),
235
+ field('result', optional(choice($.parameter_list, $._simple_type))),
236
+ field('body', optional($.block)),
237
+ )),
238
+
239
+ type_parameter_list: $ => seq(
240
+ '[',
241
+ commaSep1($.type_parameter_declaration),
242
+ optional(','),
243
+ ']',
244
+ ),
245
+
246
+ type_parameter_declaration: $ => seq(
247
+ commaSep1(field('name', $.identifier)),
248
+ field('type', alias($.type_elem, $.type_constraint)),
249
+ ),
250
+
251
+ parameter_list: $ => seq(
252
+ '(',
253
+ optional(seq(
254
+ commaSep(choice($.parameter_declaration, $.variadic_parameter_declaration)),
255
+ optional(','),
256
+ )),
257
+ ')',
258
+ ),
259
+
260
+ parameter_declaration: $ => seq(
261
+ commaSep(field('name', $.identifier)),
262
+ field('type', $._type),
263
+ ),
264
+
265
+ variadic_parameter_declaration: $ => seq(
266
+ field('name', optional($.identifier)),
267
+ '...',
268
+ field('type', $._type),
269
+ ),
270
+
271
+ type_alias: $ => seq(
272
+ field('name', $._type_identifier),
273
+ field('type_parameters', optional($.type_parameter_list)),
274
+ '=',
275
+ field('type', $._type),
276
+ ),
277
+
278
+ type_declaration: $ => seq(
279
+ 'type',
280
+ choice(
281
+ $.type_spec,
282
+ $.type_alias,
283
+ seq(
284
+ '(',
285
+ optionalTrailingSep(choice($.type_spec, $.type_alias), terminator),
286
+ ')',
287
+ ),
288
+ ),
289
+ ),
290
+
291
+ type_spec: $ => seq(
292
+ field('name', $._type_identifier),
293
+ field('type_parameters', optional($.type_parameter_list)),
294
+ field('type', $._type),
295
+ ),
296
+
297
+ field_name_list: $ => commaSep1($._field_identifier),
298
+
299
+ expression_list: $ => commaSep1($._expression),
300
+
301
+ _type: $ => choice(
302
+ $._simple_type,
303
+ $.parenthesized_type,
304
+ ),
305
+
306
+ parenthesized_type: $ => seq('(', $._type, ')'),
307
+
308
+ _simple_type: $ => choice(
309
+ prec.dynamic(-1, $._type_identifier),
310
+ $.generic_type,
311
+ $.qualified_type,
312
+ $.pointer_type,
313
+ $.struct_type,
314
+ $.interface_type,
315
+ $.array_type,
316
+ $.slice_type,
317
+ prec.dynamic(3, $.map_type),
318
+ $.channel_type,
319
+ $.function_type,
320
+ $.negated_type,
321
+ ),
322
+
323
+ generic_type: $ => prec.dynamic(1, seq(
324
+ field('type', choice($._type_identifier, $.qualified_type, $.negated_type)),
325
+ field('type_arguments', $.type_arguments),
326
+ )),
327
+
328
+ type_arguments: $ => prec.dynamic(2, seq(
329
+ '[',
330
+ commaSep1($.type_elem),
331
+ optional(','),
332
+ ']',
333
+ )),
334
+
335
+ pointer_type: $ => prec(PREC.unary, seq('*', $._type)),
336
+
337
+ array_type: $ => prec.right(seq(
338
+ '[',
339
+ field('length', $._expression),
340
+ ']',
341
+ field('element', $._type),
342
+ )),
343
+
344
+ implicit_length_array_type: $ => seq(
345
+ '[',
346
+ '...',
347
+ ']',
348
+ field('element', $._type),
349
+ ),
350
+
351
+ slice_type: $ => prec.right(seq(
352
+ '[',
353
+ ']',
354
+ field('element', $._type),
355
+ )),
356
+
357
+ struct_type: $ => seq(
358
+ 'struct',
359
+ $.field_declaration_list,
360
+ ),
361
+
362
+ negated_type: $ => prec.left(seq(
363
+ '~',
364
+ $._type,
365
+ )),
366
+
367
+ field_declaration_list: $ => seq(
368
+ '{',
369
+ optional(seq(
370
+ $.field_declaration,
371
+ repeat(seq(terminator, $.field_declaration)),
372
+ optional(terminator),
373
+ )),
374
+ '}',
375
+ ),
376
+
377
+ field_declaration: $ => seq(
378
+ choice(
379
+ seq(
380
+ commaSep1(field('name', $._field_identifier)),
381
+ field('type', $._type),
382
+ ),
383
+ seq(
384
+ optional('*'),
385
+ field('type', choice(
386
+ $._type_identifier,
387
+ $.qualified_type,
388
+ $.generic_type,
389
+ )),
390
+ ),
391
+ ),
392
+ field('tag', optional($._string_literal)),
393
+ ),
394
+
395
+ interface_type: $ => seq(
396
+ 'interface',
397
+ '{',
398
+ optional(seq(
399
+ $._interface_elem,
400
+ repeat(seq(terminator, $._interface_elem)),
401
+ optional(terminator),
402
+ )),
403
+ '}',
404
+ ),
405
+
406
+ _interface_elem: $ => choice(
407
+ $.method_elem,
408
+ $.type_elem,
409
+ ),
410
+
411
+ method_elem: $ => seq(
412
+ field('name', $._field_identifier),
413
+ field('parameters', $.parameter_list),
414
+ field('result', optional(choice($.parameter_list, $._simple_type))),
415
+ ),
416
+
417
+ type_elem: $ => sep1($._type, '|'),
418
+
419
+ map_type: $ => prec.right(seq(
420
+ 'map',
421
+ '[',
422
+ field('key', $._type),
423
+ ']',
424
+ field('value', $._type),
425
+ )),
426
+
427
+ channel_type: $ => prec.left(choice(
428
+ seq('chan', field('value', $._type)),
429
+ seq('chan', '<-', field('value', $._type)),
430
+ prec(PREC.unary, seq('<-', 'chan', field('value', $._type))),
431
+ )),
432
+
433
+ function_type: $ => prec.right(seq(
434
+ 'func',
435
+ field('parameters', $.parameter_list),
436
+ field('result', optional(choice($.parameter_list, $._simple_type))),
437
+ )),
438
+
439
+ block: $ => seq(
440
+ '{',
441
+ optional($.statement_list),
442
+ '}',
443
+ ),
444
+
445
+ statement_list: $ => choice(
446
+ seq(
447
+ $._statement,
448
+ repeat(seq(terminator, $._statement)),
449
+ optional(seq(
450
+ terminator,
451
+ optional(alias($.empty_labeled_statement, $.labeled_statement)),
452
+ )),
453
+ ),
454
+ alias($.empty_labeled_statement, $.labeled_statement),
455
+ ),
456
+
457
+ _statement: $ => choice(
458
+ $._declaration,
459
+ $._simple_statement,
460
+ $.return_statement,
461
+ $.go_statement,
462
+ $.defer_statement,
463
+ $.if_statement,
464
+ $.for_statement,
465
+ $.expression_switch_statement,
466
+ $.type_switch_statement,
467
+ $.select_statement,
468
+ $.labeled_statement,
469
+ $.fallthrough_statement,
470
+ $.break_statement,
471
+ $.continue_statement,
472
+ $.goto_statement,
473
+ $.block,
474
+ $.empty_statement,
475
+ ),
476
+
477
+ empty_statement: _ => ';',
478
+
479
+ _simple_statement: $ => choice(
480
+ $.expression_statement,
481
+ $.send_statement,
482
+ $.inc_statement,
483
+ $.dec_statement,
484
+ $.assignment_statement,
485
+ $.short_var_declaration,
486
+ ),
487
+
488
+ expression_statement: $ => $._expression,
489
+
490
+ send_statement: $ => seq(
491
+ field('channel', $._expression),
492
+ '<-',
493
+ field('value', $._expression),
494
+ ),
495
+
496
+ receive_statement: $ => seq(
497
+ optional(seq(
498
+ field('left', $.expression_list),
499
+ choice('=', ':='),
500
+ )),
501
+ field('right', $._expression),
502
+ ),
503
+
504
+ inc_statement: $ => seq(
505
+ $._expression,
506
+ '++',
507
+ ),
508
+
509
+ dec_statement: $ => seq(
510
+ $._expression,
511
+ '--',
512
+ ),
513
+
514
+ assignment_statement: $ => seq(
515
+ field('left', $.expression_list),
516
+ field('operator', choice(...assignmentOperators)),
517
+ field('right', $.expression_list),
518
+ ),
519
+
520
+ short_var_declaration: $ => seq(
521
+ // TODO: this should really only allow identifier lists, but that causes
522
+ // conflicts between identifiers as expressions vs identifiers here.
523
+ field('left', $.expression_list),
524
+ ':=',
525
+ field('right', $.expression_list),
526
+ ),
527
+
528
+ labeled_statement: $ => seq(
529
+ field('label', alias($.identifier, $.label_name)),
530
+ ':',
531
+ $._statement,
532
+ ),
533
+
534
+ empty_labeled_statement: $ => seq(
535
+ field('label', alias($.identifier, $.label_name)),
536
+ ':',
537
+ ),
538
+
539
+ // This is a hack to prevent `fallthrough_statement` from being parsed as
540
+ // a single token. For consistency with `break_statement` etc it should
541
+ // be parsed as a parent node that *contains* a `fallthrough` token.
542
+ fallthrough_statement: _ => prec.left('fallthrough'),
543
+
544
+ break_statement: $ => seq('break', optional(alias($.identifier, $.label_name))),
545
+
546
+ continue_statement: $ => seq('continue', optional(alias($.identifier, $.label_name))),
547
+
548
+ goto_statement: $ => seq('goto', alias($.identifier, $.label_name)),
549
+
550
+ return_statement: $ => seq('return', optional($.expression_list)),
551
+
552
+ go_statement: $ => seq('go', $._expression),
553
+
554
+ defer_statement: $ => seq('defer', $._expression),
555
+
556
+ if_statement: $ => seq(
557
+ 'if',
558
+ optional(seq(
559
+ field('initializer', $._simple_statement),
560
+ ';',
561
+ )),
562
+ field('condition', $._expression),
563
+ field('consequence', $.block),
564
+ optional(seq(
565
+ 'else',
566
+ field('alternative', choice($.block, $.if_statement)),
567
+ )),
568
+ ),
569
+
570
+ for_statement: $ => seq(
571
+ 'for',
572
+ optional(choice($._expression, $.for_clause, $.range_clause)),
573
+ field('body', $.block),
574
+ ),
575
+
576
+ for_clause: $ => seq(
577
+ field('initializer', optional($._simple_statement)),
578
+ ';',
579
+ field('condition', optional($._expression)),
580
+ ';',
581
+ field('update', optional($._simple_statement)),
582
+ ),
583
+
584
+ range_clause: $ => seq(
585
+ optional(seq(
586
+ field('left', $.expression_list),
587
+ choice('=', ':='),
588
+ )),
589
+ 'range',
590
+ field('right', $._expression),
591
+ ),
592
+
593
+ expression_switch_statement: $ => seq(
594
+ 'switch',
595
+ optional(seq(
596
+ field('initializer', $._simple_statement),
597
+ ';',
598
+ )),
599
+ field('value', optional($._expression)),
600
+ '{',
601
+ repeat(choice($.expression_case, $.default_case)),
602
+ '}',
603
+ ),
604
+
605
+ expression_case: $ => seq(
606
+ 'case',
607
+ field('value', $.expression_list),
608
+ ':',
609
+ optional($.statement_list),
610
+ ),
611
+
612
+ default_case: $ => seq(
613
+ 'default',
614
+ ':',
615
+ optional($.statement_list),
616
+ ),
617
+
618
+ type_switch_statement: $ => seq(
619
+ 'switch',
620
+ $._type_switch_header,
621
+ '{',
622
+ repeat(choice($.type_case, $.default_case)),
623
+ '}',
624
+ ),
625
+
626
+ _type_switch_header: $ => seq(
627
+ optional(seq(
628
+ field('initializer', $._simple_statement),
629
+ ';',
630
+ )),
631
+ optional(seq(field('alias', $.expression_list), ':=')),
632
+ field('value', $._expression),
633
+ '.',
634
+ '(',
635
+ 'type',
636
+ ')',
637
+ ),
638
+
639
+ type_case: $ => seq(
640
+ 'case',
641
+ field('type', commaSep1($._type)),
642
+ ':',
643
+ optional($.statement_list),
644
+ ),
645
+
646
+ select_statement: $ => seq(
647
+ 'select',
648
+ '{',
649
+ repeat(choice($.communication_case, $.default_case)),
650
+ '}',
651
+ ),
652
+
653
+ communication_case: $ => seq(
654
+ 'case',
655
+ field('communication', choice($.send_statement, $.receive_statement)),
656
+ ':',
657
+ optional($.statement_list),
658
+ ),
659
+
660
+ _expression: $ => choice(
661
+ $.unary_expression,
662
+ $.binary_expression,
663
+ $.selector_expression,
664
+ $.index_expression,
665
+ $.slice_expression,
666
+ $.call_expression,
667
+ $.type_assertion_expression,
668
+ $.type_conversion_expression,
669
+ $.type_instantiation_expression,
670
+ $.identifier,
671
+ alias(choice('new', 'make'), $.identifier),
672
+ $.composite_literal,
673
+ $.func_literal,
674
+ $._string_literal,
675
+ $.int_literal,
676
+ $.float_literal,
677
+ $.imaginary_literal,
678
+ $.rune_literal,
679
+ $.nil,
680
+ $.true,
681
+ $.false,
682
+ $.iota,
683
+ $.parenthesized_expression,
684
+ ),
685
+
686
+ parenthesized_expression: $ => seq(
687
+ '(',
688
+ $._expression,
689
+ ')',
690
+ ),
691
+
692
+ call_expression: $ => prec(PREC.primary, choice(
693
+ seq(
694
+ field('function', alias(choice('new', 'make'), $.identifier)),
695
+ field('arguments', alias($.special_argument_list, $.argument_list)),
696
+ ),
697
+ seq(
698
+ field('function', $._expression),
699
+ field('type_arguments', optional($.type_arguments)),
700
+ field('arguments', $.argument_list),
701
+ ),
702
+ )),
703
+
704
+ variadic_argument: $ => prec.right(seq(
705
+ $._expression,
706
+ '...',
707
+ )),
708
+
709
+ special_argument_list: $ => seq(
710
+ '(',
711
+ optional(seq(
712
+ $._type,
713
+ repeat(seq(',', $._expression)),
714
+ optional(','),
715
+ )),
716
+ ')',
717
+ ),
718
+
719
+ argument_list: $ => seq(
720
+ '(',
721
+ optional(seq(
722
+ choice($._expression, $.variadic_argument),
723
+ repeat(seq(',', choice($._expression, $.variadic_argument))),
724
+ optional(','),
725
+ )),
726
+ ')',
727
+ ),
728
+
729
+ selector_expression: $ => prec(PREC.primary, seq(
730
+ field('operand', $._expression),
731
+ '.',
732
+ field('field', $._field_identifier),
733
+ )),
734
+
735
+ index_expression: $ => prec(PREC.primary, prec.dynamic(1, seq(
736
+ field('operand', $._expression),
737
+ '[',
738
+ field('index', $._expression),
739
+ ']',
740
+ ))),
741
+
742
+ slice_expression: $ => prec(PREC.primary, seq(
743
+ field('operand', $._expression),
744
+ '[',
745
+ choice(
746
+ seq(
747
+ field('start', optional($._expression)),
748
+ ':',
749
+ field('end', optional($._expression)),
750
+ ),
751
+ seq(
752
+ field('start', optional($._expression)),
753
+ ':',
754
+ field('end', $._expression),
755
+ ':',
756
+ field('capacity', $._expression),
757
+ ),
758
+ ),
759
+ ']',
760
+ )),
761
+
762
+ type_assertion_expression: $ => prec(PREC.primary, seq(
763
+ field('operand', $._expression),
764
+ '.',
765
+ '(',
766
+ field('type', $._type),
767
+ ')',
768
+ )),
769
+
770
+ type_conversion_expression: $ => prec.dynamic(-1, seq(
771
+ field('type', $._type),
772
+ '(',
773
+ field('operand', $._expression),
774
+ optional(','),
775
+ ')',
776
+ )),
777
+
778
+ type_instantiation_expression: $ => prec.dynamic(-1, seq(
779
+ field('type', $._type),
780
+ '[',
781
+ commaSep1($._type),
782
+ optional(','),
783
+ ']',
784
+ )),
785
+
786
+ composite_literal: $ => prec(PREC.composite_literal, seq(
787
+ field('type', choice(
788
+ $.map_type,
789
+ $.slice_type,
790
+ $.array_type,
791
+ $.implicit_length_array_type,
792
+ $.struct_type,
793
+ $._type_identifier,
794
+ $.generic_type,
795
+ $.qualified_type,
796
+ )),
797
+ field('body', $.literal_value),
798
+ )),
799
+
800
+ literal_value: $ => seq(
801
+ '{',
802
+ optional(
803
+ seq(
804
+ commaSep(choice($.literal_element, $.keyed_element)),
805
+ optional(','))),
806
+ '}',
807
+ ),
808
+
809
+ literal_element: $ => choice($._expression, $.literal_value),
810
+
811
+ // In T{k: v}, the key k may be:
812
+ // - any expression (when T is a map, slice or array),
813
+ // - a field identifier (when T is a struct), or
814
+ // - a literal_element (when T is an array).
815
+ // The first two cases cannot be distinguished without type information.
816
+ keyed_element: $ => seq(
817
+ field('key', $.literal_element),
818
+ ':',
819
+ field('value', $.literal_element),
820
+ ),
821
+
822
+ func_literal: $ => seq(
823
+ 'func',
824
+ field('parameters', $.parameter_list),
825
+ field('result', optional(choice($.parameter_list, $._simple_type))),
826
+ field('body', $.block),
827
+ ),
828
+
829
+ unary_expression: $ => prec(PREC.unary, seq(
830
+ field('operator', choice('+', '-', '!', '^', '*', '&', '<-')),
831
+ field('operand', $._expression),
832
+ )),
833
+
834
+ binary_expression: $ => {
835
+ const table = [
836
+ [PREC.multiplicative, choice(...multiplicativeOperators)],
837
+ [PREC.additive, choice(...additiveOperators)],
838
+ [PREC.comparative, choice(...comparativeOperators)],
839
+ [PREC.and, '&&'],
840
+ [PREC.or, '||'],
841
+ ];
842
+
843
+ return choice(...table.map(([precedence, operator]) =>
844
+ // @ts-ignore
845
+ prec.left(precedence, seq(
846
+ field('left', $._expression),
847
+ // @ts-ignore
848
+ field('operator', operator),
849
+ field('right', $._expression),
850
+ )),
851
+ ));
852
+ },
853
+
854
+ qualified_type: $ => seq(
855
+ field('package', $._package_identifier),
856
+ '.',
857
+ field('name', $._type_identifier),
858
+ ),
859
+
860
+ identifier: _ => /[_\p{XID_Start}][_\p{XID_Continue}]*/,
861
+
862
+ _type_identifier: $ => alias($.identifier, $.type_identifier),
863
+ _field_identifier: $ => alias($.identifier, $.field_identifier),
864
+ _package_identifier: $ => alias($.identifier, $.package_identifier),
865
+
866
+ _string_literal: $ => choice(
867
+ $.raw_string_literal,
868
+ $.interpreted_string_literal,
869
+ ),
870
+
871
+ raw_string_literal: $ => seq(
872
+ '`',
873
+ alias(token(prec(1, /[^`]*/)), $.raw_string_literal_content),
874
+ '`',
875
+ ),
876
+
877
+ interpreted_string_literal: $ => seq(
878
+ '"',
879
+ repeat(choice(
880
+ alias(token.immediate(prec(1, /[^"\n\\]+/)), $.interpreted_string_literal_content),
881
+ $.escape_sequence,
882
+ )),
883
+ token.immediate('"'),
884
+ ),
885
+
886
+ escape_sequence: _ => token.immediate(seq(
887
+ '\\',
888
+ choice(
889
+ /[^xuU]/,
890
+ /\d{2,3}/,
891
+ /x[0-9a-fA-F]{2,}/,
892
+ /u[0-9a-fA-F]{4}/,
893
+ /U[0-9a-fA-F]{8}/,
894
+ ),
895
+ )),
896
+
897
+ int_literal: _ => token(intLiteral),
898
+
899
+ float_literal: _ => token(floatLiteral),
900
+
901
+ imaginary_literal: _ => token(imaginaryLiteral),
902
+
903
+ rune_literal: _ => token(seq(
904
+ '\'',
905
+ choice(
906
+ /[^'\\]/,
907
+ seq(
908
+ '\\',
909
+ choice(
910
+ seq('x', hexDigit, hexDigit),
911
+ seq(octalDigit, octalDigit, octalDigit),
912
+ seq('u', hexDigit, hexDigit, hexDigit, hexDigit),
913
+ seq('U', hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit),
914
+ seq(choice('a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"')),
915
+ ),
916
+ ),
917
+ ),
918
+ '\'',
919
+ )),
920
+
921
+ nil: _ => 'nil',
922
+ true: _ => 'true',
923
+ false: _ => 'false',
924
+ iota: _ => 'iota',
925
+
926
+ // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
927
+ comment: _ => token(choice(
928
+ seq('//', /.*/),
929
+ seq(
930
+ '/*',
931
+ /[^*]*\*+([^/*][^*]*\*+)*/,
932
+ '/',
933
+ ),
934
+ )),
935
+ },
936
+ });
937
+
938
+ /**
939
+ * Creates a rule to match one or more occurrences of `rule` separated by `sep`
940
+ *
941
+ * @param {RuleOrLiteral} rule
942
+ *
943
+ * @param {RuleOrLiteral} separator
944
+ *
945
+ * @returns {SeqRule}
946
+ */
947
+ function sep1(rule, separator) {
948
+ return seq(rule, repeat(seq(separator, rule)));
949
+ }
950
+
951
+ /**
952
+ * Creates a rule to match zero or more of the rules separated by {sep},
953
+ * with an optional one at the end.
954
+ *
955
+ * @param {RuleOrLiteral} rule
956
+ *
957
+ * @param {RuleOrLiteral} separator
958
+ */
959
+ function optionalTrailingSep(rule, separator) {
960
+ return optional(seq(rule, repeat(seq(separator, rule)), optional(separator)));
961
+ }
962
+
963
+ /**
964
+ * Creates a rule to match one or more of the rules separated by a comma
965
+ *
966
+ * @param {Rule} rule
967
+ *
968
+ * @returns {SeqRule}
969
+ */
970
+ function commaSep1(rule) {
971
+ return seq(rule, repeat(seq(',', rule)));
972
+ }
973
+
974
+ /**
975
+ * Creates a rule to optionally match one or more of the rules separated by a comma
976
+ *
977
+ * @param {Rule} rule
978
+ *
979
+ * @returns {ChoiceRule}
980
+ */
981
+ function commaSep(rule) {
982
+ return optional(commaSep1(rule));
983
+ }