-
Notifications
You must be signed in to change notification settings - Fork 4
/
parser.lalrpop
1125 lines (1012 loc) · 53.4 KB
/
parser.lalrpop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
use lang_util::position::LexerPosition;
use glsl_lang_lexer::{IdentifierContext, Token, HasLexerError};
use crate::{
ast::{self, NodeContent},
parse::ParseContext,
};
grammar<'i, L>(ctx: &ParseContext) where L: HasLexerError;
comma<T>: Vec<T> = {
<e:T?> <v:("," <T>)*> => match e {
None => v,
Some(e) => {
let mut v = v;
v.insert(0, e);
v
}
}
};
comma_trailing<T>: Vec<T> = {
<v:(<T> ",")*> <e:T?> => match e {
None => v,
Some(e) => {
let mut v = v;
v.push(e);
v
}
}
};
identifier: ast::Identifier = {
<l:@L> <i:ident> <r:@R> => ast::IdentifierData::from(i.as_str()).spanned(l, r),
};
type_name: ast::TypeName = {
<l:@L> <i:ty_name> <r:@R> => ast::TypeNameData::from(i.as_str()).spanned(l, r),
};
primary_expression: ast::Expr = {
<l:@L> <e:identifier> <r:@R> => ast::ExprData::Variable(e).spanned(l, r),
<l:@L> <e:double_constant> <r:@R> => ast::ExprData::DoubleConst(e.into()).spanned(l, r),
<l:@L> <e:float_constant> <r:@R> => ast::ExprData::FloatConst(e.into()).spanned(l, r),
<l:@L> <e:uint_constant> <r:@R> => ast::ExprData::UIntConst(e.into()).spanned(l, r),
<l:@L> <e:int_constant> <r:@R> => ast::ExprData::IntConst(e.into()).spanned(l, r),
<l:@L> <e:bool_constant> <r:@R> => ast::ExprData::BoolConst(e.into()).spanned(l, r),
"(" <expr> ")",
};
postfix_expression: ast::Expr = {
primary_expression,
<a:@L> <l:postfix_expression> "[" <e:expr> "]" <b:@R> =>
ast::ExprData::Bracket(Box::new(l), Box::new(e)).spanned(a, b),
function_call,
<a:@L> <l:postfix_expression> "." <r:identifier> <b:@R> => ast::ExprData::Dot(Box::new(l), r).spanned(a, b),
<a:@L> <e:postfix_expression> "++" <b:@R> => ast::ExprData::PostInc(Box::new(e)).spanned(a, b),
<a:@L> <e:postfix_expression> "--" <b:@R> => ast::ExprData::PostDec(Box::new(e)).spanned(a, b),
};
integer_expression = {
expr
};
function_call: ast::Expr = {
<a:@L> <i:fun_identifier> "(" <e:comma<assignment_expression>> ")" <b:@R> =>
ast::ExprData::FunCall(i, e).spanned(a, b),
<a:@L> <i:fun_identifier> "(" "void" ")" <b:@R> =>
ast::ExprData::FunCall(i, vec![]).spanned(a, b),
};
array_specifier_dimension_data: ast::ArraySpecifierDimensionData = {
"[" "]" => ast::ArraySpecifierDimensionData::Unsized,
"[" <conditional_expression> "]" => ast::ArraySpecifierDimensionData::ExplicitlySized(Box::new(<>)),
};
array_specifier_dimension: ast::ArraySpecifierDimension = {
<l:@L> <a:array_specifier_dimension_data> <r:@R> => a.spanned(l, r)
};
array_specifier: ast::ArraySpecifier = {
<l:@L> <a:array_specifier_dimension+> <r:@R> => ast::ArraySpecifierData {
dimensions: a,
}.spanned(l, r)
};
struct_field_specifier: ast::StructFieldSpecifier = {
<l:@L> <q:type_qualifier?> <s:type_specifier> <f:comma<arrayed_identifier>> ";" <r:@R> => ast::StructFieldSpecifierData {
qualifier: q,
ty: s,
identifiers: f,
}.spanned(l, r)
};
struct_specifier: ast::StructSpecifier = {
<l:@L> "struct" <i:identifier?> "{" <s:struct_field_specifier*> "}" <r:@R> => ast::StructSpecifierData {
name: i.map(|ident| ctx.add_type_name(ident)),
fields: s,
}.spanned(l, r),
};
type_specifier_non_struct: ast::TypeSpecifierNonArrayData = {
"void" => ast::TypeSpecifierNonArrayData::Void,
"bool" => ast::TypeSpecifierNonArrayData::Bool,
"int" => ast::TypeSpecifierNonArrayData::Int,
"uint" => ast::TypeSpecifierNonArrayData::UInt,
"float" => ast::TypeSpecifierNonArrayData::Float,
"double" => ast::TypeSpecifierNonArrayData::Double,
"vec2" => ast::TypeSpecifierNonArrayData::Vec2,
"vec3" => ast::TypeSpecifierNonArrayData::Vec3,
"vec4" => ast::TypeSpecifierNonArrayData::Vec4,
"dvec2" => ast::TypeSpecifierNonArrayData::DVec2,
"dvec3" => ast::TypeSpecifierNonArrayData::DVec3,
"dvec4" => ast::TypeSpecifierNonArrayData::DVec4,
"bvec2" => ast::TypeSpecifierNonArrayData::BVec2,
"bvec3" => ast::TypeSpecifierNonArrayData::BVec3,
"bvec4" => ast::TypeSpecifierNonArrayData::BVec4,
"ivec2" => ast::TypeSpecifierNonArrayData::IVec2,
"ivec3" => ast::TypeSpecifierNonArrayData::IVec3,
"ivec4" => ast::TypeSpecifierNonArrayData::IVec4,
"uvec2" => ast::TypeSpecifierNonArrayData::UVec2,
"uvec3" => ast::TypeSpecifierNonArrayData::UVec3,
"uvec4" => ast::TypeSpecifierNonArrayData::UVec4,
"mat2" => ast::TypeSpecifierNonArrayData::Mat2,
"mat3" => ast::TypeSpecifierNonArrayData::Mat3,
"mat4" => ast::TypeSpecifierNonArrayData::Mat4,
"mat2x2" => ast::TypeSpecifierNonArrayData::Mat22,
"mat2x3" => ast::TypeSpecifierNonArrayData::Mat23,
"mat2x4" => ast::TypeSpecifierNonArrayData::Mat24,
"mat3x2" => ast::TypeSpecifierNonArrayData::Mat32,
"mat3x3" => ast::TypeSpecifierNonArrayData::Mat33,
"mat3x4" => ast::TypeSpecifierNonArrayData::Mat34,
"mat4x2" => ast::TypeSpecifierNonArrayData::Mat42,
"mat4x3" => ast::TypeSpecifierNonArrayData::Mat43,
"mat4x4" => ast::TypeSpecifierNonArrayData::Mat44,
"dmat2" => ast::TypeSpecifierNonArrayData::DMat2,
"dmat3" => ast::TypeSpecifierNonArrayData::DMat3,
"dmat4" => ast::TypeSpecifierNonArrayData::DMat4,
"dmat2x2" => ast::TypeSpecifierNonArrayData::DMat22,
"dmat2x3" => ast::TypeSpecifierNonArrayData::DMat23,
"dmat2x4" => ast::TypeSpecifierNonArrayData::DMat24,
"dmat3x2" => ast::TypeSpecifierNonArrayData::DMat32,
"dmat3x3" => ast::TypeSpecifierNonArrayData::DMat33,
"dmat3x4" => ast::TypeSpecifierNonArrayData::DMat34,
"dmat4x2" => ast::TypeSpecifierNonArrayData::DMat42,
"dmat4x3" => ast::TypeSpecifierNonArrayData::DMat43,
"dmat4x4" => ast::TypeSpecifierNonArrayData::DMat44,
"sampler1D" => ast::TypeSpecifierNonArrayData::Sampler1D,
"image1D" => ast::TypeSpecifierNonArrayData::Image1D,
"sampler2D" => ast::TypeSpecifierNonArrayData::Sampler2D,
"image2D" => ast::TypeSpecifierNonArrayData::Image2D,
"sampler3D" => ast::TypeSpecifierNonArrayData::Sampler3D,
"image3D" => ast::TypeSpecifierNonArrayData::Image3D,
"samplerCube" => ast::TypeSpecifierNonArrayData::SamplerCube,
"imageCube" => ast::TypeSpecifierNonArrayData::ImageCube,
"sampler2DRect" => ast::TypeSpecifierNonArrayData::Sampler2DRect,
"image2DRect" => ast::TypeSpecifierNonArrayData::Image2DRect,
"sampler1DArray" => ast::TypeSpecifierNonArrayData::Sampler1DArray,
"image1DArray" => ast::TypeSpecifierNonArrayData::Image1DArray,
"sampler2DArray" => ast::TypeSpecifierNonArrayData::Sampler2DArray,
"image2DArray" => ast::TypeSpecifierNonArrayData::Image2DArray,
"samplerBuffer" => ast::TypeSpecifierNonArrayData::SamplerBuffer,
"imageBuffer" => ast::TypeSpecifierNonArrayData::ImageBuffer,
"sampler2DMS" => ast::TypeSpecifierNonArrayData::Sampler2DMs,
"image2DMS" => ast::TypeSpecifierNonArrayData::Image2DMs,
"sampler2DMSArray" => ast::TypeSpecifierNonArrayData::Sampler2DMsArray,
"image2DMSArray" => ast::TypeSpecifierNonArrayData::Image2DMsArray,
"samplerCubeArray" => ast::TypeSpecifierNonArrayData::SamplerCubeArray,
"imageCubeArray" => ast::TypeSpecifierNonArrayData::ImageCubeArray,
"sampler1DShadow" => ast::TypeSpecifierNonArrayData::Sampler1DShadow,
"sampler2DShadow" => ast::TypeSpecifierNonArrayData::Sampler2DShadow,
"sampler2DRectShadow" => ast::TypeSpecifierNonArrayData::Sampler2DRectShadow,
"sampler1DArrayShadow" => ast::TypeSpecifierNonArrayData::Sampler1DArrayShadow,
"sampler2DArrayShadow" => ast::TypeSpecifierNonArrayData::Sampler2DArrayShadow,
"samplerCubeShadow" => ast::TypeSpecifierNonArrayData::SamplerCubeShadow,
"samplerCubeArrayShadow" => ast::TypeSpecifierNonArrayData::SamplerCubeArrayShadow,
"isampler1D" => ast::TypeSpecifierNonArrayData::ISampler1D,
"iimage1D" => ast::TypeSpecifierNonArrayData::IImage1D,
"isampler2D" => ast::TypeSpecifierNonArrayData::ISampler2D,
"iimage2D" => ast::TypeSpecifierNonArrayData::IImage2D,
"isampler3D" => ast::TypeSpecifierNonArrayData::ISampler3D,
"iimage3D" => ast::TypeSpecifierNonArrayData::IImage3D,
"isamplerCube" => ast::TypeSpecifierNonArrayData::ISamplerCube,
"iimageCube" => ast::TypeSpecifierNonArrayData::IImageCube,
"isampler2DRect" => ast::TypeSpecifierNonArrayData::ISampler2DRect,
"iimage2DRect" => ast::TypeSpecifierNonArrayData::IImage2DRect,
"isampler1DArray" => ast::TypeSpecifierNonArrayData::ISampler1DArray,
"iimage1DArray" => ast::TypeSpecifierNonArrayData::IImage1DArray,
"isampler2DArray" => ast::TypeSpecifierNonArrayData::ISampler2DArray,
"iimage2DArray" => ast::TypeSpecifierNonArrayData::IImage2DArray,
"isamplerBuffer" => ast::TypeSpecifierNonArrayData::ISamplerBuffer,
"iimageBuffer" => ast::TypeSpecifierNonArrayData::IImageBuffer,
"isampler2DMS" => ast::TypeSpecifierNonArrayData::ISampler2DMs,
"iimage2DMS" => ast::TypeSpecifierNonArrayData::IImage2DMs,
"isampler2DMSArray" => ast::TypeSpecifierNonArrayData::ISampler2DMsArray,
"iimage2DMSArray" => ast::TypeSpecifierNonArrayData::IImage2DMsArray,
"isamplerCubeArray" => ast::TypeSpecifierNonArrayData::ISamplerCubeArray,
"iimageCubeArray" => ast::TypeSpecifierNonArrayData::IImageCubeArray,
"atomic_uint" => ast::TypeSpecifierNonArrayData::AtomicUInt,
"usampler1D" => ast::TypeSpecifierNonArrayData::USampler1D,
"uimage1D" => ast::TypeSpecifierNonArrayData::UImage1D,
"usampler2D" => ast::TypeSpecifierNonArrayData::USampler2D,
"uimage2D" => ast::TypeSpecifierNonArrayData::UImage2D,
"usampler3D" => ast::TypeSpecifierNonArrayData::USampler3D,
"uimage3D" => ast::TypeSpecifierNonArrayData::UImage3D,
"usamplerCube" => ast::TypeSpecifierNonArrayData::USamplerCube,
"uimageCube" => ast::TypeSpecifierNonArrayData::UImageCube,
"usampler2DRect" => ast::TypeSpecifierNonArrayData::USampler2DRect,
"uimage2DRect" => ast::TypeSpecifierNonArrayData::UImage2DRect,
"usampler1DArray" => ast::TypeSpecifierNonArrayData::USampler1DArray,
"uimage1DArray" => ast::TypeSpecifierNonArrayData::UImage1DArray,
"usampler2DArray" => ast::TypeSpecifierNonArrayData::USampler2DArray,
"uimage2DArray" => ast::TypeSpecifierNonArrayData::UImage2DArray,
"usamplerBuffer" => ast::TypeSpecifierNonArrayData::USamplerBuffer,
"uimageBuffer" => ast::TypeSpecifierNonArrayData::UImageBuffer,
"usampler2DMS" => ast::TypeSpecifierNonArrayData::USampler2DMs,
"uimage2DMS" => ast::TypeSpecifierNonArrayData::UImage2DMs,
"usampler2DMSArray" => ast::TypeSpecifierNonArrayData::USampler2DMsArray,
"uimage2DMSArray" => ast::TypeSpecifierNonArrayData::UImage2DMsArray,
"usamplerCubeArray" => ast::TypeSpecifierNonArrayData::USamplerCubeArray,
"uimageCubeArray" => ast::TypeSpecifierNonArrayData::UImageCubeArray,
// added by GL_KHR_vulkan_glsl
"texture1D" => ast::TypeSpecifierNonArrayData::Texture1D,
"texture2D" => ast::TypeSpecifierNonArrayData::Texture2D,
"texture3D" => ast::TypeSpecifierNonArrayData::Texture3D,
"textureCube" => ast::TypeSpecifierNonArrayData::TextureCube,
"texture2DRect" => ast::TypeSpecifierNonArrayData::Texture2DRect,
"texture1DArray" => ast::TypeSpecifierNonArrayData::Texture1DArray,
"texture2DArray" => ast::TypeSpecifierNonArrayData::Texture2DArray,
"textureBuffer" => ast::TypeSpecifierNonArrayData::TextureBuffer,
"texture2DMS" => ast::TypeSpecifierNonArrayData::Texture2DMs,
"texture2DMSArray" => ast::TypeSpecifierNonArrayData::Texture2DMsArray,
"textureCubeArray" => ast::TypeSpecifierNonArrayData::TextureCubeArray,
"itexture1D" => ast::TypeSpecifierNonArrayData::ITexture1D,
"itexture2D" => ast::TypeSpecifierNonArrayData::ITexture2D,
"itexture3D" => ast::TypeSpecifierNonArrayData::ITexture3D,
"itextureCube" => ast::TypeSpecifierNonArrayData::ITextureCube,
"itexture2DRect" => ast::TypeSpecifierNonArrayData::ITexture2DRect,
"itexture1DArray" => ast::TypeSpecifierNonArrayData::ITexture1DArray,
"itexture2DArray" => ast::TypeSpecifierNonArrayData::ITexture2DArray,
"itextureBuffer" => ast::TypeSpecifierNonArrayData::ITextureBuffer,
"itexture2DMS" => ast::TypeSpecifierNonArrayData::ITexture2DMs,
"itexture2DMSArray" => ast::TypeSpecifierNonArrayData::ITexture2DMsArray,
"itextureCubeArray" => ast::TypeSpecifierNonArrayData::ITextureCubeArray,
"sampler" => ast::TypeSpecifierNonArrayData::Sampler,
"samplerShadow" => ast::TypeSpecifierNonArrayData::SamplerShadow,
"subpassInput" => ast::TypeSpecifierNonArrayData::SubpassInput,
"isubpassInput" => ast::TypeSpecifierNonArrayData::ISubpassInput,
"usubpassInput" => ast::TypeSpecifierNonArrayData::USubpassInput,
"subpassInputMS" => ast::TypeSpecifierNonArrayData::SubpassInputMs,
"isubpassInputMS" => ast::TypeSpecifierNonArrayData::ISubpassInputMs,
"usubpassInputMS" => ast::TypeSpecifierNonArrayData::USubpassInputMs,
};
type_specifier_non_array: ast::TypeSpecifierNonArray = {
<l:@L> <t:type_specifier_non_struct> <r:@R> => t.spanned(l, r),
<l:@L> <s:struct_specifier> <r:@R> => ast::TypeSpecifierNonArrayData::Struct(s).spanned(l, r),
<l:@L> <t:type_name> <r:@R> => ast::TypeSpecifierNonArrayData::TypeName(t).spanned(l, r),
};
type_specifier: ast::TypeSpecifier = {
<l:@L> <t:type_specifier_non_array> <a:array_specifier?> <r:@R> =>
ast::TypeSpecifierData { ty: t, array_specifier: a }.spanned(l, r)
};
type_qualifier_spec_data: ast::TypeQualifierSpecData = {
<storage_qualifier> => ast::TypeQualifierSpecData::Storage(<>),
<layout_qualifier> => ast::TypeQualifierSpecData::Layout(<>),
<precision_qualifier> => ast::TypeQualifierSpecData::Precision(<>),
<interpolation_qualifier> => ast::TypeQualifierSpecData::Interpolation(<>),
"precise" => ast::TypeQualifierSpecData::Precise,
};
type_qualifier_spec: ast::TypeQualifierSpec = {
<l:@L> <s:type_qualifier_spec_data> <r:@R> => s.spanned(l, r)
};
tq_invariant_data: ast::TypeQualifierSpecData = {
"invariant" => ast::TypeQualifierSpecData::Invariant,
};
tq_invariant: ast::TypeQualifierSpec = {
<l:@L> <s:tq_invariant_data> <r:@R> => s.spanned(l, r)
};
type_qualifier: ast::TypeQualifier = {
<l:@L> <q1:tq_invariant?> <q2:type_qualifier_spec+> <r:@R> => ast::TypeQualifierData {
qualifiers: q1.into_iter().chain(q2.into_iter()).collect()
}.spanned(l, r)
};
fully_specified_type: ast::FullySpecifiedType = {
<l:@L> <q:type_qualifier?> <s:type_specifier> <r:@R> =>
ast::FullySpecifiedTypeData { qualifier: q, ty: s }.spanned(l, r)
};
fun_identifier_data: ast::FunIdentifierData = {
type_specifier => ast::FunIdentifierData::TypeSpecifier(Box::new(<>)),
postfix_expression => ast::FunIdentifierData::Expr(Box::new(<>)),
};
fun_identifier: ast::FunIdentifier = {
<l:@L> <i:fun_identifier_data> <r:@R> => i.spanned(l, r)
};
unary_expression: ast::Expr = {
postfix_expression,
<a:@L> <o:unary_op> <e:unary_expression> <b:@R> => ast::ExprData::Unary(o, Box::new(e)).spanned(a, b),
};
unary_op_data: ast::UnaryOpData = {
"+" => ast::UnaryOpData::Add,
"-" => ast::UnaryOpData::Minus,
"!" => ast::UnaryOpData::Not,
"~" => ast::UnaryOpData::Complement,
"++" => ast::UnaryOpData::Inc,
"--" => ast::UnaryOpData::Dec,
};
unary_op: ast::UnaryOp = {
<l:@L> <u:unary_op_data> <r:@R> => u.spanned(l, r)
};
arrayed_identifier: ast::ArrayedIdentifier = {
<l:@L> <i:identifier> <a:array_specifier?> <r:@R> =>
ast::ArrayedIdentifierData { ident: i, array_spec: a }.spanned(l, r),
};
multiplicative_expression: ast::Expr = {
unary_expression,
<a:@L> <l:multiplicative_expression> <c:@L> "*" <d:@R> <r:unary_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Mult.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:multiplicative_expression> <c:@L> "/" <d:@R> <r:unary_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Div.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:multiplicative_expression> <c:@L> "%" <d:@R> <r:unary_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Mod.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
additive_expression: ast::Expr = {
multiplicative_expression,
<a:@L> <l:additive_expression> <c:@L> "+" <d:@R> <r:multiplicative_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Add.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:additive_expression> <c:@L> "-" <d:@R> <r:multiplicative_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Sub.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
shift_expression: ast::Expr = {
additive_expression,
<a:@L> <l:shift_expression> <c:@L> "<<" <d:@R> <r:additive_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::LShift.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:shift_expression> <c:@L> ">>" <d:@R> <r:additive_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::RShift.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
relational_expression: ast::Expr = {
shift_expression,
<a:@L> <l:relational_expression> <c:@L> "<" <d:@R> <r:shift_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Lt.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:relational_expression> <c:@L> ">" <d:@R> <r:shift_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Gt.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:relational_expression> <c:@L> "<=" <d:@R> <r:shift_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Lte.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:relational_expression> <c:@L> ">=" <d:@R> <r:shift_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Gte.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
equality_expression: ast::Expr = {
relational_expression,
<a:@L> <l:equality_expression> <c:@L> "==" <d:@R> <r:relational_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Equal.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
<a:@L> <l:equality_expression> <c:@L> "!=" <d:@R> <r:relational_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::NonEqual.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
and_expression: ast::Expr = {
equality_expression,
<a:@L> <l:and_expression> <c:@L> "&" <d:@R> <r:equality_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::BitAnd.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
exclusive_or_expression: ast::Expr = {
and_expression,
<a:@L> <l:exclusive_or_expression> <c:@L> "^" <d:@R> <r:and_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::BitXor.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
inclusive_or_expression: ast::Expr = {
exclusive_or_expression,
<a:@L> <l:inclusive_or_expression> <c:@L> "|" <d:@R> <r:exclusive_or_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::BitOr.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
logical_and_expression: ast::Expr = {
inclusive_or_expression,
<a:@L> <l:logical_and_expression> <c:@L> "&&" <d:@R> <r:inclusive_or_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::And.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
logical_xor_expression: ast::Expr = {
logical_and_expression,
<a:@L> <l:logical_xor_expression> <c:@L> "^^" <d:@R> <r:logical_and_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Xor.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
logical_or_expression: ast::Expr = {
logical_xor_expression,
<a:@L> <l:logical_or_expression> <c:@L> "||" <d:@R> <r:logical_xor_expression> <b:@R> =>
ast::ExprData::Binary(ast::BinaryOpData::Or.spanned(c, d), Box::new(l), Box::new(r)).spanned(a, b),
};
conditional_expression: ast::Expr = {
logical_or_expression,
<a:@L> <c:logical_or_expression> "?" <l:expr> ":" <r:assignment_expression> <b:@R> =>
ast::ExprData::Ternary(Box::new(c), Box::new(l), Box::new(r)).spanned(a, b),
};
assignment_expression: ast::Expr = {
conditional_expression,
<a:@L> <l:unary_expression> <o:assignment_op> <r:assignment_expression> <b:@R> =>
ast::ExprData::Assignment(Box::new(l), o, Box::new(r)).spanned(a, b),
};
assignment_op_data: ast::AssignmentOpData = {
"=" => ast::AssignmentOpData::Equal,
"*=" => ast::AssignmentOpData::Mult,
"/=" => ast::AssignmentOpData::Div,
"%=" => ast::AssignmentOpData::Mod,
"+=" => ast::AssignmentOpData::Add,
"-=" => ast::AssignmentOpData::Sub,
"<<=" => ast::AssignmentOpData::LShift,
">>=" => ast::AssignmentOpData::RShift,
"&=" => ast::AssignmentOpData::And,
"^=" => ast::AssignmentOpData::Xor,
"|=" => ast::AssignmentOpData::Or,
};
assignment_op: ast::AssignmentOp = {
<l:@L> <o:assignment_op_data> <r:@R> => o.spanned(l, r)
};
expr: ast::Expr = {
assignment_expression,
<a:@L> <l:expr> "," <r:assignment_expression> <b:@R> =>
ast::ExprData::Comma(Box::new(l), Box::new(r)).spanned(a, b),
};
expr_statement: ast::ExprStatement = {
<l:@L> <e:expr?> ";" <r:@R> => ast::ExprStatementData(e).spanned(l, r),
};
selection_statement_else<S>: ast::SelectionStatement = {
<a:@L> "if" "(" <e:expr> ")" <c:@L> <r:statement_no_short_if> "else" <s:S> <d:@R> <b:@R> => ast::SelectionStatementData {
cond: Box::new(e),
rest: ast::SelectionRestStatementData::Else(Box::new(r), Box::new(s)).spanned(c, d),
}.spanned(a, b)
};
selection_statement<S>: ast::SelectionStatement = {
<a:@L> "if" "(" <e:expr> ")" <c:@L> <r:statement> <d:@R> <b:@R> => ast::SelectionStatementData {
cond: Box::new(e),
rest: ast::SelectionRestStatementData::Statement(Box::new(r)).spanned(c, d),
}.spanned(a, b),
selection_statement_else<S>,
};
switch_statement: ast::SwitchStatement = {
<a:@L> "switch" "(" <e:expr> ")" "{" <s:statement*> "}" <b:@R> => ast::SwitchStatementData {
head: Box::new(e),
body: s,
}.spanned(a, b)
};
case_label_data: ast::CaseLabelData = {
"case" <expr> ":" => ast::CaseLabelData::Case(Box::new(<>)),
"default" ":" => ast::CaseLabelData::Def,
};
case_label: ast::CaseLabel = {
<l:@L> <c:case_label_data> <r:@R> => c.spanned(l, r)
};
initializer_data: ast::InitializerData = {
<assignment_expression> => ast::InitializerData::Simple(Box::new(<>)),
"{" <comma_trailing<initializer>> "}" => ast::InitializerData::List(<>),
};
initializer: ast::Initializer = {
<l:@L> <i:initializer_data> <r:@R> => i.spanned(l, r)
};
condition_data: ast::ConditionData = {
<expr> => ast::ConditionData::Expr(<>),
<t:fully_specified_type> <i:identifier> "=" <e:initializer> => ast::ConditionData::Assignment(Box::new(t), i, e),
};
condition: ast::Condition = {
<l:@L> <c:condition_data> <r:@R> => c.spanned(l, r)
};
for_init_statement_data: ast::ForInitStatementData = {
<expr_statement> => ast::ForInitStatementData::Expression(<>.content.0),
<declaration> => ast::ForInitStatementData::Declaration(Box::new(<>)),
};
for_init_statement: ast::ForInitStatement = {
<l:@L> <f:for_init_statement_data> <r:@R> => f.spanned(l, r)
};
for_rest_statement: ast::ForRestStatement = {
<l:@L> <c:condition?> ";" <e:expr?> <r:@R> =>
ast::ForRestStatementData { condition: c, post_expr: e.map(Box::new) }.spanned(l, r)
};
iteration_statement<S>: ast::IterationStatement = {
<a:@L> "while" "(" <c:condition> ")" <s:S> <b:@R> =>
ast::IterationStatementData::While(c, Box::new(s)).spanned(a, b),
<a:@L> "do" <s:statement> "while" "(" <c:expr> ")" ";" <b:@R> =>
ast::IterationStatementData::DoWhile(Box::new(s), Box::new(c)).spanned(a, b),
<a:@L> "for" "(" <init:for_init_statement> <rest:for_rest_statement> ")" <s:S> <b:@R> =>
ast::IterationStatementData::For(init, rest, Box::new(s)).spanned(a, b),
};
jump_statement_data: ast::JumpStatementData = {
"continue" ";" => ast::JumpStatementData::Continue,
"break" ";" => ast::JumpStatementData::Break,
"discard" ";" => ast::JumpStatementData::Discard,
"return" <e:expr?> ";" => ast::JumpStatementData::Return(e.map(Box::new)),
};
jump_statement: ast::JumpStatement = {
<l:@L> <j:jump_statement_data> <r:@R> => j.spanned(l, r)
};
simple_statement<S, I>: ast::Statement = {
<l:@L> <s:jump_statement> <r:@R> => ast::StatementData::Jump(s).spanned(l, r),
<l:@L> <s:iteration_statement<S>> <r:@R> => ast::StatementData::Iteration(s).spanned(l, r),
<l:@L> <s:case_label> <r:@R> => ast::StatementData::CaseLabel(s).spanned(l, r),
<l:@L> <s:switch_statement> <r:@R> => ast::StatementData::Switch(s).spanned(l, r),
<l:@L> <s:I> <r:@R> => ast::StatementData::Selection(s).spanned(l, r),
<l:@L> <s:declaration> <r:@R> => ast::StatementData::Declaration(s).spanned(l, r),
<l:@L> <s:expr_statement> <r:@R> => ast::StatementData::Expression(s).spanned(l, r),
};
compound_statement: ast::CompoundStatement = {
<l:@L> "{" <s:statement*> "}" <r:@R> => ast::CompoundStatementData { statement_list: s }.spanned(l, r),
};
statement: ast::Statement = {
compound_statement => <>.map_spanned(ast::StatementData::Compound),
simple_statement<statement, selection_statement<statement>>,
};
statement_no_short_if: ast::Statement = {
compound_statement => <>.map_spanned(ast::StatementData::Compound),
simple_statement<statement_no_short_if, selection_statement_else<statement_no_short_if>>,
};
interpolation_qualifier_data: ast::InterpolationQualifierData = {
"smooth" => ast::InterpolationQualifierData::Smooth,
"flat" => ast::InterpolationQualifierData::Flat,
"noperspective" => ast::InterpolationQualifierData::NoPerspective,
};
interpolation_qualifier: ast::InterpolationQualifier = {
<l:@L> <i:interpolation_qualifier_data> <r:@R> => i.spanned(l, r)
};
precision_qualifier_data: ast::PrecisionQualifierData = {
"highp" => ast::PrecisionQualifierData::High,
"mediump" => ast::PrecisionQualifierData::Medium,
"lowp" => ast::PrecisionQualifierData::Low,
};
precision_qualifier: ast::PrecisionQualifier = {
<l:@L> <p:precision_qualifier_data> <r:@R> => p.spanned(l, r)
};
storage_qualifier_data: ast::StorageQualifierData = {
"const" => ast::StorageQualifierData::Const,
"inout" => ast::StorageQualifierData::InOut,
"in" => ast::StorageQualifierData::In,
"out" => ast::StorageQualifierData::Out,
"centroid" => ast::StorageQualifierData::Centroid,
"patch" => ast::StorageQualifierData::Patch,
"sample" => ast::StorageQualifierData::Sample,
"uniform" => ast::StorageQualifierData::Uniform,
"buffer" => ast::StorageQualifierData::Buffer,
"shared" => ast::StorageQualifierData::Shared,
"coherent" => ast::StorageQualifierData::Coherent,
"volatile" => ast::StorageQualifierData::Volatile,
"restrict" => ast::StorageQualifierData::Restrict,
"readonly" => ast::StorageQualifierData::ReadOnly,
"writeonly" => ast::StorageQualifierData::WriteOnly,
"attribute" => ast::StorageQualifierData::Attribute,
"varying" => ast::StorageQualifierData::Varying,
"subroutine" <t:("(" <comma<type_specifier>> ")")?> =>
ast::StorageQualifierData::Subroutine(t.unwrap_or_else(|| vec![])),
};
storage_qualifier: ast::StorageQualifier = {
<l:@L> <s:storage_qualifier_data> <r:@R> => s.spanned(l, r)
};
layout_qualifier_spec_data: ast::LayoutQualifierSpecData = {
"shared" => ast::LayoutQualifierSpecData::Shared,
<i:identifier> "=" <c:conditional_expression> => ast::LayoutQualifierSpecData::Identifier(i, Some(Box::new(c))),
<identifier> => ast::LayoutQualifierSpecData::Identifier(<>, None),
};
layout_qualifier_spec: ast::LayoutQualifierSpec = {
<l:@L> <s:layout_qualifier_spec_data> <r:@R> => s.spanned(l, r)
};
layout_qualifier: ast::LayoutQualifier = {
<l:@L> "layout" "(" <s:comma<layout_qualifier_spec>> ")" <r:@R> =>
ast::LayoutQualifierData { ids: s }.spanned(l, r),
};
precision_declaration: ast::DeclarationData = {
"precision" <q:precision_qualifier> <t:type_specifier> => ast::DeclarationData::Precision(q, t),
};
function_parameter_declarator: ast::FunctionParameterDeclarator = {
<l:@L> <s:type_specifier> <i:arrayed_identifier> <r:@R> => ast::FunctionParameterDeclaratorData {
ty: s,
ident: i,
}.spanned(l, r)
};
function_parameter_declaration: ast::FunctionParameterDeclaration = {
<l:@L> <q:type_qualifier?> <s:type_specifier> <r:@R> =>
ast::FunctionParameterDeclarationData::Unnamed(q, s).spanned(l, r),
<l:@L> <q:type_qualifier?> <d:function_parameter_declarator> <r:@R> =>
ast::FunctionParameterDeclarationData::Named(q, d).spanned(l, r),
}
function_prototype: ast::FunctionPrototype = {
<l:@L> <rt:fully_specified_type> <n:identifier> "(" <p:comma<function_parameter_declaration>> ")" <r:@R> =>
ast::FunctionPrototypeData {
ty: rt,
name: n,
parameters: p,
}.spanned(l, r),
};
single_declaration_data: ast::SingleDeclarationData = {
<t:fully_specified_type> <i:arrayed_identifier> <e:("=" <initializer>)?> => {
let i = i.into_inner();
ast::SingleDeclarationData {
ty: t,
name: Some(i.ident),
array_specifier: i.array_spec,
initializer: e,
}
},
<t:fully_specified_type> => ast::SingleDeclarationData {
ty: t,
name: None,
array_specifier: None,
initializer: None,
},
};
single_declaration: ast::SingleDeclaration = {
<l:@L> <s:single_declaration_data> <r:@R> => s.spanned(l, r)
};
single_declaration_no_type: ast::SingleDeclarationNoType = {
<l:@L> <i:arrayed_identifier> <e:("=" <initializer>)?> <r:@R> => ast::SingleDeclarationNoTypeData {
ident: i,
initializer: e,
}.spanned(l, r)
};
init_declarator_list: ast::InitDeclaratorList = {
<l:@L> <h:single_declaration> <t:("," <single_declaration_no_type>)*> <r:@R> => ast::InitDeclaratorListData {
head: h,
tail: t,
}.spanned(l, r)
};
block_declaration: ast::Block = {
<l:@L> <q:type_qualifier> <n:identifier> "{" <f:struct_field_specifier*> "}" <a:arrayed_identifier?> <r:@R> =>
ast::BlockData { qualifier: q, name: n, fields: f, identifier: a }.spanned(l, r)
};
declaration: ast::Declaration = {
<l:@L> <p:function_prototype> ";" <r:@R> => {
ctx.new_identifier(&p.name, IdentifierContext::FunctionPrototype);
ast::DeclarationData::FunctionPrototype(p).spanned(l, r)
},
<l:@L> <i:init_declarator_list> ";" <r:@R> => ast::DeclarationData::InitDeclaratorList(i).spanned(l, r),
<l:@L> <p:precision_declaration> ";" <r:@R> => p.spanned(l, r),
<l:@L> <b:block_declaration> ";" <r:@R> => ast::DeclarationData::Block(b).spanned(l, r),
<l:@L> "invariant" <i:identifier> ";" <r:@R> => ast::DeclarationData::Invariant(i).spanned(l, r),
<l:@L> <q:type_qualifier> ";" <r:@R> => ast::DeclarationData::TypeOnly(q).spanned(l, r),
};
function_definition: ast::FunctionDefinition = {
<l:@L> <p:function_prototype> <s:compound_statement> <r:@R> => ast::FunctionDefinitionData {
prototype: p,
statement: s,
}.spanned(l, r)
};
pp_define_object_like: ast::PreprocessorDefineData = {
<i:identifier> <r:pp_rest> => ast::PreprocessorDefineData::ObjectLike {
ident: i,
value: r.into(),
}
}
pp_define_function_like: ast::PreprocessorDefineData = {
<i:identifier> "(" <p:comma<identifier>> ")" <r:pp_rest> => ast::PreprocessorDefineData::FunctionLike {
ident: i,
args: p,
value: r.into(),
}
}
preprocessor_define_data = {
pp_define_function_like,
pp_define_object_like,
};
preprocessor_define: ast::PreprocessorDefine = {
<l:@L> <d:preprocessor_define_data> <r:@R> => d.spanned(l, r),
};
preprocessor_else_if: ast::PreprocessorElseIf = {
<l:@L> <p:pp_rest> <r:@R> => ast::PreprocessorElseIfData { condition: p.into() }.spanned(l, r)
};
preprocessor_error: ast::PreprocessorError = {
<l:@L> <p:pp_rest> <r:@R> => ast::PreprocessorErrorData { message: p.into() }.spanned(l, r)
};
preprocessor_if: ast::PreprocessorIf = {
<l:@L> <p:pp_rest> <r:@R> => ast::PreprocessorIfData { condition: p.into() }.spanned(l, r)
};
preprocessor_if_def: ast::PreprocessorIfDef = {
<l:@L> <i:identifier> <r:@R> => ast::PreprocessorIfDefData { ident: i }.spanned(l, r)
};
preprocessor_if_n_def: ast::PreprocessorIfNDef = {
<l:@L> <i:identifier> <r:@R> => ast::PreprocessorIfNDefData { ident: i }.spanned(l, r)
};
preprocessor_include: ast::PreprocessorInclude = {
<l:@L> <p:pp_path_relative> <r:@R> =>
ast::PreprocessorIncludeData {
path: ast::PathData::Relative(p.as_str().to_owned()).spanned(l, r)
}.spanned(l, r),
<l:@L> <p:pp_path_absolute> <r:@R> =>
ast::PreprocessorIncludeData {
path: ast::PathData::Absolute(p.as_str().to_owned()).spanned(l, r)
}.spanned(l, r),
};
preprocessor_line: ast::PreprocessorLine = {
<l:@L> <i:int_constant> <f:int_constant?> <r:@R> => ast::PreprocessorLineData {
line: <Token as Into<i32>>::into(i) as u32,
source_string_number: f.map(|n| <Token as Into<i32>>::into(n) as u32),
}.spanned(l, r)
};
preprocessor_pragma: ast::PreprocessorPragma = {
<l:@L> <p:pp_rest> <r:@R> => ast::PreprocessorPragmaData { command: p.into() }.spanned(l, r)
};
preprocessor_undef: ast::PreprocessorUndef = {
<l:@L> <n:identifier> <r:@R> => ast::PreprocessorUndefData { name: n }.spanned(l, r)
};
preprocessor_version_profile_data: ast::PreprocessorVersionProfileData = {
"core" => ast::PreprocessorVersionProfileData::Core,
"compatibility" => ast::PreprocessorVersionProfileData::Compatibility,
"es" => ast::PreprocessorVersionProfileData::Es,
};
preprocessor_version_profile: ast::PreprocessorVersionProfile = {
<l:@L> <p:preprocessor_version_profile_data> <r:@R> => p.spanned(l, r)
};
preprocessor_version: ast::PreprocessorVersion = {
<l:@L> <v:int_constant> <p:preprocessor_version_profile?> <r:@R> => ast::PreprocessorVersionData {
version: <Token as Into<i32>>::into(v) as u16,
profile: p,
}.spanned(l, r)
};
preprocessor_extension_behavior_data: ast::PreprocessorExtensionBehaviorData = {
"require" => ast::PreprocessorExtensionBehaviorData::Require,
"enable" => ast::PreprocessorExtensionBehaviorData::Enable,
"warn" => ast::PreprocessorExtensionBehaviorData::Warn,
"disable" => ast::PreprocessorExtensionBehaviorData::Disable,
};
preprocessor_extension_behavior: ast::PreprocessorExtensionBehavior = {
<l:@L> <p:preprocessor_extension_behavior_data> <r:@R> => p.spanned(l, r)
};
preprocessor_extension: ast::PreprocessorExtension = {
<l:@L> <i:ident> <b:(":" <preprocessor_extension_behavior>)?> <r:@R> => ast::PreprocessorExtensionData {
name: if i.as_str() == "all" {
ast::PreprocessorExtensionNameData::All.spanned(l, r)
} else {
ast::PreprocessorExtensionNameData::Specific(i.as_str().into()).spanned(l, r)
},
behavior: b,
}.spanned(l, r)
};
preprocessor: ast::Preprocessor = {
<l:@L> "#define" <p:preprocessor_define> <r:@R> => ast::PreprocessorData::Define(p).spanned(l, r),
<l:@L> "#else" <r:@R> => ast::PreprocessorData::Else.spanned(l, r),
<l:@L> "#elif" <p:preprocessor_else_if> <r:@R> => ast::PreprocessorData::ElseIf(p).spanned(l, r),
<l:@L> "#endif" <r:@R> => ast::PreprocessorData::EndIf.spanned(l, r),
<l:@L> "#error" <p:preprocessor_error> <r:@R> => ast::PreprocessorData::Error(p).spanned(l, r),
<l:@L> "#if" <p:preprocessor_if> <r:@R> => ast::PreprocessorData::If(p).spanned(l, r),
<l:@L> "#ifdef" <p:preprocessor_if_def> <r:@R> => ast::PreprocessorData::IfDef(p).spanned(l, r),
<l:@L> "#ifndef" <p:preprocessor_if_n_def> <r:@R> => ast::PreprocessorData::IfNDef(p).spanned(l, r),
<l:@L> "#include" <p:preprocessor_include> <r:@R> => ast::PreprocessorData::Include(p).spanned(l, r),
<l:@L> "#line" <p:preprocessor_line> <r:@R> => ast::PreprocessorData::Line(p).spanned(l, r),
<l:@L> "#pragma" <p:preprocessor_pragma> <r:@R> => ast::PreprocessorData::Pragma(p).spanned(l, r),
<l:@L> "#undef" <p:preprocessor_undef> <r:@R> => ast::PreprocessorData::Undef(p).spanned(l, r),
<l:@L> "#version" <p:preprocessor_version> <r:@R> => ast::PreprocessorData::Version(p).spanned(l, r),
<l:@L> "#extension" <p:preprocessor_extension> <r:@R> => ast::PreprocessorData::Extension(p).spanned(l, r),
};
external_declaration: Option<ast::ExternalDeclaration> = {
<l:@L> <p:preprocessor> <r:@R> => Some(ast::ExternalDeclarationData::Preprocessor(p).spanned(l, r)),
<l:@L> <f:function_definition> <r:@R> => Some(ast::ExternalDeclarationData::FunctionDefinition(f).spanned(l, r)),
<l:@L> <d:declaration> <r:@R> => Some(ast::ExternalDeclarationData::Declaration(d).spanned(l, r)),
";" => None,
};
translation_unit: ast::TranslationUnit = {
<external_declaration*> => ast::TranslationUnit(<>.into_iter().filter_map(|d| d).collect())
};
#[cfg(feature = "parser-expr")]
pub Expr = { expr };
#[cfg(feature = "parser-statement")]
pub Statement = { statement };
pub TranslationUnit = { translation_unit };
extern {
type Location = LexerPosition;
type Error = L::Error;
enum Token {
ident => Token::Identifier(_),
ty_name => Token::TypeName(_),
int_constant => Token::IntConstant(_),
uint_constant => Token::UIntConstant(_),
bool_constant => Token::BoolConstant(_),
float_constant => Token::FloatConstant(_),
double_constant => Token::DoubleConstant(_),
"(" => Token::LeftParen,
")" => Token::RightParen,
"[" => Token::LeftBracket,
"]" => Token::RightBracket,
"." => Token::Dot,
"++" => Token::IncOp,
"--" => Token::DecOp,
"void" => Token::Void,
"+" => Token::Plus,
"-" => Token::Dash,
"!" => Token::Bang,
"~" => Token::Tilde,
"*" => Token::Star,
"/" => Token::Slash,
"%" => Token::Percent,
"<<" => Token::LeftOp,
">>" => Token::RightOp,
"<" => Token::LeftAngle,
">" => Token::RightAngle,
"<=" => Token::LeOp,
">=" => Token::GeOp,
"==" => Token::EqOp,
"!=" => Token::NeOp,
"&" => Token::Ampersand,
"^" => Token::Caret,
"|" => Token::VerticalBar,
"&&" => Token::AndOp,
"^^" => Token::XorOp,
"||" => Token::OrOp,
"?" => Token::Question,
":" => Token::Colon,
"=" => Token::Equal,
"*=" => Token::MulAssign,
"/=" => Token::DivAssign,
"%=" => Token::ModAssign,
"+=" => Token::AddAssign,
"-=" => Token::SubAssign,
"<<=" => Token::LeftAssign,
">>=" => Token::RightAssign,
"&=" => Token::AndAssign,
"^=" => Token::XorAssign,
"|=" => Token::OrAssign,
"," => Token::Comma,
"{" => Token::LeftBrace,
"}" => Token::RightBrace,
";" => Token::Semicolon,
"smooth" => Token::Smooth,
"flat" => Token::Flat,
"noperspective" => Token::NoPerspective,
"highp" => Token::HighPrecision,
"mediump" => Token::MediumPrecision,
"lowp" => Token::LowPrecision,
"const" => Token::Const,
"inout" => Token::InOut,
"in" => Token::In,
"out" => Token::Out,
"centroid" => Token::Centroid,
"patch" => Token::Patch,
"sample" => Token::Sample,
"uniform" => Token::Uniform,
"buffer" => Token::Buffer,
"shared" => Token::Shared,
"coherent" => Token::Coherent,
"volatile" => Token::Volatile,
"restrict" => Token::Restrict,
"readonly" => Token::ReadOnly,
"writeonly" => Token::WriteOnly,
"attribute" => Token::Attribute,
"varying" => Token::Varying,
"subroutine" => Token::Subroutine,
"layout" => Token::Layout,
"precision" => Token::Precision,
"void" => Token::Void,
"bool" => Token::Bool,
"int" => Token::Int,
"uint" => Token::UInt,
"float" => Token::Float,
"double" => Token::Double,
"vec2" => Token::Vec2,
"vec3" => Token::Vec3,
"vec4" => Token::Vec4,
"dvec2" => Token::DVec2,
"dvec3" => Token::DVec3,
"dvec4" => Token::DVec4,
"bvec2" => Token::BVec2,
"bvec3" => Token::BVec3,
"bvec4" => Token::BVec4,
"ivec2" => Token::IVec2,
"ivec3" => Token::IVec3,
"ivec4" => Token::IVec4,
"uvec2" => Token::UVec2,
"uvec3" => Token::UVec3,
"uvec4" => Token::UVec4,
"mat2" => Token::Mat2,
"mat3" => Token::Mat3,
"mat4" => Token::Mat4,
"mat2x2" => Token::Mat2x2,
"mat2x3" => Token::Mat2x3,
"mat2x4" => Token::Mat2x4,
"mat3x2" => Token::Mat3x2,
"mat3x3" => Token::Mat3x3,
"mat3x4" => Token::Mat3x4,
"mat4x2" => Token::Mat4x2,
"mat4x3" => Token::Mat4x3,
"mat4x4" => Token::Mat4x4,
"dmat2" => Token::DMat2,
"dmat3" => Token::DMat3,
"dmat4" => Token::DMat4,
"dmat2x2" => Token::DMat2x2,
"dmat2x3" => Token::DMat2x3,
"dmat2x4" => Token::DMat2x4,
"dmat3x2" => Token::DMat3x2,
"dmat3x3" => Token::DMat3x3,
"dmat3x4" => Token::DMat3x4,
"dmat4x2" => Token::DMat4x2,
"dmat4x3" => Token::DMat4x3,
"dmat4x4" => Token::DMat4x4,
"sampler1D" => Token::Sampler1D,
"image1D" => Token::Image1D,
"sampler2D" => Token::Sampler2D,
"image2D" => Token::Image2D,
"sampler3D" => Token::Sampler3D,
"image3D" => Token::Image3D,
"samplerCube" => Token::SamplerCube,
"imageCube" => Token::ImageCube,
"sampler2DRect" => Token::Sampler2DRect,
"image2DRect" => Token::Image2DRect,
"sampler1DArray" => Token::Sampler1DArray,
"image1DArray" => Token::Image1DArray,
"sampler2DArray" => Token::Sampler2DArray,
"image2DArray" => Token::Image2DArray,
"samplerBuffer" => Token::SamplerBuffer,
"imageBuffer" => Token::ImageBuffer,
"sampler2DMS" => Token::Sampler2DMs,
"image2DMS" => Token::Image2DMs,
"sampler2DMSArray" => Token::Sampler2DMsArray,
"image2DMSArray" => Token::Image2DMsArray,
"samplerCubeArray" => Token::SamplerCubeArray,
"imageCubeArray" => Token::ImageCubeArray,