1 /*
2 //
3 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7 
8 This file contains the Yacc grammar for GLSL ES.
9 Based on ANSI C Yacc grammar:
10 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
11 
12 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
13 WHICH GENERATES THE GLSL ES PARSER (glslang_tab_autogen.cpp AND glslang_tab_autogen.h).
14 */
15 
16 %{
17 // GENERATED FILE - DO NOT EDIT.
18 // Generated by generate_parser.py from glslang.y
19 //
20 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
21 // Use of this source code is governed by a BSD-style license that can be
22 // found in the LICENSE file.
23 //
24 // glslang.y:
25 //   Parser for the OpenGL shading language.
26 
27 // Ignore errors in auto-generated code.
28 #if defined(__GNUC__)
29 #pragma GCC diagnostic ignored "-Wunused-function"
30 #pragma GCC diagnostic ignored "-Wunused-variable"
31 #pragma GCC diagnostic ignored "-Wswitch-enum"
32 #elif defined(_MSC_VER)
33 #pragma warning(disable: 4065)
34 #pragma warning(disable: 4189)
35 #pragma warning(disable: 4244)
36 #pragma warning(disable: 4505)
37 #pragma warning(disable: 4701)
38 #pragma warning(disable: 4702)
39 #endif
40 #if defined(__clang__)
41 #pragma clang diagnostic ignored "-Wunreachable-code"
42 #endif
43 
44 #include "angle_gl.h"
45 #include "compiler/translator/Declarator.h"
46 #include "compiler/translator/SymbolTable.h"
47 #include "compiler/translator/ParseContext.h"
48 #include "GLSLANG/ShaderLang.h"
49 
50 #define YYENABLE_NLS 0
51 
52 using namespace sh;
53 
54 %}
55 %expect 1 /* One shift reduce conflict because of if | else */
56 %parse-param {TParseContext* context}
57 %param   {void *scanner}
58 %define api.pure full
59 %locations
60 
61 %code requires {
62 #define YYLTYPE TSourceLoc
63 #define YYLTYPE_IS_DECLARED 1
64 #define YYLTYPE_IS_TRIVIAL 1
65 }
66 
67 %union {
68     struct {
69         union {
70             const char *string;  // pool allocated.
71             float f;
72             int i;
73             unsigned int u;
74             bool b;
75         };
76         const TSymbol* symbol;
77     } lex;
78     struct {
79         TOperator op;
80         union {
81             TIntermNode *intermNode;
82             TIntermNodePair nodePair;
83             TIntermTyped *intermTypedNode;
84             TIntermAggregate *intermAggregate;
85             TIntermBlock *intermBlock;
86             TIntermDeclaration *intermDeclaration;
87             TIntermFunctionPrototype *intermFunctionPrototype;
88             TIntermSwitch *intermSwitch;
89             TIntermCase *intermCase;
90         };
91         union {
92             TVector<unsigned int> *arraySizes;
93             TTypeSpecifierNonArray typeSpecifierNonArray;
94             TPublicType type;
95             TPrecision precision;
96             TLayoutQualifier layoutQualifier;
97             TQualifier qualifier;
98             TFunction *function;
99             TFunctionLookup *functionLookup;
100             TParameter param;
101             TDeclarator *declarator;
102             TDeclaratorList *declaratorList;
103             TFieldList *fieldList;
104             TQualifierWrapperBase *qualifierWrapper;
105             TTypeQualifierBuilder *typeQualifierBuilder;
106         };
107     } interm;
108 }
109 
110 %{
111 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
112 extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, const char* reason);
113 
114 #define YYLLOC_DEFAULT(Current, Rhs, N)                      \
115   do {                                                       \
116       if (N) {                                         \
117         (Current).first_file = YYRHSLOC(Rhs, 1).first_file;  \
118         (Current).first_line = YYRHSLOC(Rhs, 1).first_line;  \
119         (Current).last_file = YYRHSLOC(Rhs, N).last_file;    \
120         (Current).last_line = YYRHSLOC(Rhs, N).last_line;    \
121       }                                                      \
122       else {                                                 \
123         (Current).first_file = YYRHSLOC(Rhs, 0).last_file;   \
124         (Current).first_line = YYRHSLOC(Rhs, 0).last_line;   \
125         (Current).last_file = YYRHSLOC(Rhs, 0).last_file;    \
126         (Current).last_line = YYRHSLOC(Rhs, 0).last_line;    \
127       }                                                      \
128   } while (0)
129 
130 #define VERTEX_ONLY(S, L) do {  \
131     if (context->getShaderType() != GL_VERTEX_SHADER) {  \
132         context->error(L, " supported in vertex shaders only", S);  \
133     }  \
134 } while (0)
135 
136 #define COMPUTE_ONLY(S, L) do {  \
137     if (context->getShaderType() != GL_COMPUTE_SHADER) {  \
138         context->error(L, " supported in compute shaders only", S);  \
139     }  \
140 } while (0)
141 
142 #define ES2_ONLY(S, L) do {  \
143     if (context->getShaderVersion() != 100) {  \
144         context->error(L, " supported in GLSL ES 1.00 only", S);  \
145     }  \
146 } while (0)
147 
148 #define ES3_OR_NEWER(TOKEN, LINE, REASON) do {  \
149     if (context->getShaderVersion() < 300) {  \
150         context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN);  \
151     }  \
152 } while (0)
153 
154 #define ES3_1_ONLY(TOKEN, LINE, REASON) do {  \
155     if (context->getShaderVersion() != 310) {  \
156         context->error(LINE, REASON " supported in GLSL ES 3.10 only", TOKEN);  \
157     }  \
158 } while (0)
159 %}
160 
161 %token <lex> INVARIANT PRECISE HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
162 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE
163 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
164 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4
165 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM BUFFER VARYING
166 %token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3
167 %token <lex> SAMPLE CENTROID FLAT SMOOTH NOPERSPECTIVE
168 %token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED
169 %token <lex> STRUCT VOID_TYPE WHILE
170 %token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY
171 %token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY
172 %token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY
173 %token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
174 %token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
175 %token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW SAMPLERVIDEOWEBGL
176 %token <lex> SAMPLERCUBEARRAYOES SAMPLERCUBEARRAYSHADOWOES ISAMPLERCUBEARRAYOES USAMPLERCUBEARRAYOES
177 %token <lex> SAMPLERCUBEARRAYEXT SAMPLERCUBEARRAYSHADOWEXT ISAMPLERCUBEARRAYEXT USAMPLERCUBEARRAYEXT
178 %token <lex> SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER
179 %token <lex> SAMPLEREXTERNAL2DY2YEXT
180 %token <lex> IMAGE2D IIMAGE2D UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
181 %token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
182 %token <lex> IMAGECUBEARRAYOES IIMAGECUBEARRAYOES UIMAGECUBEARRAYOES
183 %token <lex> IMAGECUBEARRAYEXT IIMAGECUBEARRAYEXT UIMAGECUBEARRAYEXT
184 %token <lex> IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
185 %token <lex> ATOMICUINT
186 %token <lex> LAYOUT
187 %token <lex> YUVCSCSTANDARDEXT YUVCSCSTANDARDEXTCONSTANT
188 
189 %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
190 %token <lex> FIELD_SELECTION
191 %token <lex> LEFT_OP RIGHT_OP
192 %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
193 %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
194 %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
195 %token <lex> SUB_ASSIGN
196 
197 %token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
198 %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
199 %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
200 
201 %type <lex> identifier
202 %type <interm.op> assignment_operator unary_operator
203 %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
204 %type <interm.intermTypedNode> expression integer_expression assignment_expression
205 %type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
206 %type <interm.intermTypedNode> relational_expression equality_expression
207 %type <interm.intermTypedNode> conditional_expression constant_expression
208 %type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
209 %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
210 %type <interm.intermTypedNode> function_call initializer
211 
212 %type <interm.intermNode> condition conditionopt
213 %type <interm.intermBlock> translation_unit
214 %type <interm.intermNode> function_definition statement simple_statement
215 %type <interm.intermBlock> statement_list compound_statement_with_scope compound_statement_no_new_scope
216 %type <interm.intermNode> declaration_statement selection_statement expression_statement
217 %type <interm.intermNode> declaration external_declaration
218 %type <interm.intermNode> for_init_statement
219 %type <interm.nodePair> selection_rest_statement for_rest_statement
220 %type <interm.intermSwitch> switch_statement
221 %type <interm.intermCase> case_label
222 %type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
223 %type <interm> single_declaration init_declarator_list
224 
225 %type <interm.param> parameter_declaration parameter_declarator parameter_type_specifier
226 %type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id
227 
228 // Note: array_specifier guaranteed to be non-null.
229 %type <interm.arraySizes> array_specifier
230 
231 %type <interm.type> fully_specified_type type_specifier
232 
233 %type <interm.precision> precision_qualifier
234 %type <interm.layoutQualifier> layout_qualifier
235 %type <interm.qualifier> interpolation_qualifier
236 %type <interm.qualifierWrapper> storage_qualifier single_type_qualifier invariant_qualifier precise_qualifier
237 %type <interm.typeQualifierBuilder> type_qualifier
238 
239 %type <interm.typeSpecifierNonArray> type_specifier_nonarray struct_specifier
240 %type <interm.type> type_specifier_no_prec
241 %type <interm.declarator> struct_declarator
242 %type <interm.declaratorList> struct_declarator_list
243 %type <interm.fieldList> struct_declaration struct_declaration_list
244 %type <interm.function> function_header function_declarator
245 %type <interm.function> function_header_with_parameters
246 %type <interm.functionLookup> function_identifier function_call_header
247 %type <interm.functionLookup> function_call_header_with_parameters function_call_header_no_parameters
248 %type <interm.functionLookup> function_call_generic function_call_or_method
249 %type <interm> function_prototype
250 
251 %type <lex> enter_struct
252 
253 %start translation_unit
254 %%
255 
256 identifier
257     : IDENTIFIER
258     | TYPE_NAME
259 
260 variable_identifier
261     : IDENTIFIER {
262         // The symbol table search was done in the lexical phase
263         $$ = context->parseVariableIdentifier(@1, ImmutableString($1.string), $1.symbol);
264     }
265     ;
266 
267 primary_expression
268     : variable_identifier {
269         $$ = $1;
270     }
271     | INTCONSTANT {
272         TConstantUnion *unionArray = new TConstantUnion[1];
273         unionArray->setIConst($1.i);
274         $$ = context->addScalarLiteral(unionArray, @1);
275     }
276     | UINTCONSTANT {
277         TConstantUnion *unionArray = new TConstantUnion[1];
278         unionArray->setUConst($1.u);
279         $$ = context->addScalarLiteral(unionArray, @1);
280     }
281     | FLOATCONSTANT {
282         TConstantUnion *unionArray = new TConstantUnion[1];
283         unionArray->setFConst($1.f);
284         $$ = context->addScalarLiteral(unionArray, @1);
285     }
286     | BOOLCONSTANT {
287         TConstantUnion *unionArray = new TConstantUnion[1];
288         unionArray->setBConst($1.b);
289         $$ = context->addScalarLiteral(unionArray, @1);
290     }
291     | YUVCSCSTANDARDEXTCONSTANT {
292         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
293         {
294            context->error(@1, "unsupported value", ImmutableString($1.string));
295         }
296         TConstantUnion *unionArray = new TConstantUnion[1];
297         unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT(ImmutableString($1.string)));
298         $$ = context->addScalarLiteral(unionArray, @1);
299     }
300     | LEFT_PAREN expression RIGHT_PAREN {
301         $$ = $2;
302     }
303     ;
304 
305 postfix_expression
306     : primary_expression {
307         $$ = $1;
308     }
309     | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
310         $$ = context->addIndexExpression($1, @2, $3);
311     }
312     | function_call {
313         $$ = $1;
314     }
315     | postfix_expression DOT FIELD_SELECTION {
316         $$ = context->addFieldSelectionExpression($1, @2, ImmutableString($3.string), @3);
317     }
318     | postfix_expression INC_OP {
319         $$ = context->addUnaryMathLValue(EOpPostIncrement, $1, @2);
320     }
321     | postfix_expression DEC_OP {
322         $$ = context->addUnaryMathLValue(EOpPostDecrement, $1, @2);
323     }
324     ;
325 
326 integer_expression
327     : expression {
328         context->checkIsScalarInteger($1, "[]");
329         $$ = $1;
330     }
331     ;
332 
333 function_call
334     : function_call_or_method {
335         $$ = context->addFunctionCallOrMethod($1, @1);
336     }
337     ;
338 
339 function_call_or_method
340     : function_call_generic {
341         $$ = $1;
342     }
343     | postfix_expression DOT function_call_generic {
344         ES3_OR_NEWER("", @3, "methods");
345         $$ = $3;
346         $$->setThisNode($1);
347     }
348     ;
349 
350 function_call_generic
351     : function_call_header_with_parameters RIGHT_PAREN {
352         $$ = $1;
353     }
354     | function_call_header_no_parameters RIGHT_PAREN {
355         $$ = $1;
356     }
357     ;
358 
359 function_call_header_no_parameters
360     : function_call_header VOID_TYPE {
361         $$ = $1;
362     }
363     | function_call_header {
364         $$ = $1;
365     }
366     ;
367 
368 function_call_header_with_parameters
369     : function_call_header assignment_expression {
370         $$ = $1;
371         $$->addArgument($2);
372     }
373     | function_call_header_with_parameters COMMA assignment_expression {
374         $$ = $1;
375         $$->addArgument($3);
376     }
377     ;
378 
379 function_call_header
380     : function_identifier LEFT_PAREN {
381         $$ = $1;
382     }
383     ;
384 
385 // Grammar Note:  Constructors look like functions, but are recognized as types.
386 
387 function_identifier
388     : type_specifier_no_prec {
389         $$ = context->addConstructorFunc($1);
390     }
391     | IDENTIFIER {
392         $$ = context->addNonConstructorFunc(ImmutableString($1.string), $1.symbol);
393     }
394     | FIELD_SELECTION {
395         $$ = context->addNonConstructorFunc(ImmutableString($1.string), $1.symbol);
396     }
397     ;
398 
399 unary_expression
400     : postfix_expression {
401         $$ = $1;
402     }
403     | INC_OP unary_expression {
404         $$ = context->addUnaryMathLValue(EOpPreIncrement, $2, @1);
405     }
406     | DEC_OP unary_expression {
407         $$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1);
408     }
409     | unary_operator unary_expression {
410         $$ = context->addUnaryMath($1, $2, @1);
411     }
412     ;
413 // Grammar Note:  No traditional style type casts.
414 
415 unary_operator
416     : PLUS  { $$ = EOpPositive; }
417     | DASH  { $$ = EOpNegative; }
418     | BANG  { $$ = EOpLogicalNot; }
419     | TILDE {
420         ES3_OR_NEWER("~", @$, "bit-wise operator");
421         $$ = EOpBitwiseNot;
422     }
423     ;
424 // Grammar Note:  No '*' or '&' unary ops.  Pointers are not supported.
425 
426 multiplicative_expression
427     : unary_expression { $$ = $1; }
428     | multiplicative_expression STAR unary_expression {
429         $$ = context->addBinaryMath(EOpMul, $1, $3, @2);
430     }
431     | multiplicative_expression SLASH unary_expression {
432         $$ = context->addBinaryMath(EOpDiv, $1, $3, @2);
433     }
434     | multiplicative_expression PERCENT unary_expression {
435         ES3_OR_NEWER("%", @2, "integer modulus operator");
436         $$ = context->addBinaryMath(EOpIMod, $1, $3, @2);
437     }
438     ;
439 
440 additive_expression
441     : multiplicative_expression { $$ = $1; }
442     | additive_expression PLUS multiplicative_expression {
443         $$ = context->addBinaryMath(EOpAdd, $1, $3, @2);
444     }
445     | additive_expression DASH multiplicative_expression {
446         $$ = context->addBinaryMath(EOpSub, $1, $3, @2);
447     }
448     ;
449 
450 shift_expression
451     : additive_expression { $$ = $1; }
452     | shift_expression LEFT_OP additive_expression {
453         ES3_OR_NEWER("<<", @2, "bit-wise operator");
454         $$ = context->addBinaryMath(EOpBitShiftLeft, $1, $3, @2);
455     }
456     | shift_expression RIGHT_OP additive_expression {
457         ES3_OR_NEWER(">>", @2, "bit-wise operator");
458         $$ = context->addBinaryMath(EOpBitShiftRight, $1, $3, @2);
459     }
460     ;
461 
462 relational_expression
463     : shift_expression { $$ = $1; }
464     | relational_expression LEFT_ANGLE shift_expression {
465         $$ = context->addBinaryMathBooleanResult(EOpLessThan, $1, $3, @2);
466     }
467     | relational_expression RIGHT_ANGLE shift_expression  {
468         $$ = context->addBinaryMathBooleanResult(EOpGreaterThan, $1, $3, @2);
469     }
470     | relational_expression LE_OP shift_expression  {
471         $$ = context->addBinaryMathBooleanResult(EOpLessThanEqual, $1, $3, @2);
472     }
473     | relational_expression GE_OP shift_expression  {
474         $$ = context->addBinaryMathBooleanResult(EOpGreaterThanEqual, $1, $3, @2);
475     }
476     ;
477 
478 equality_expression
479     : relational_expression { $$ = $1; }
480     | equality_expression EQ_OP relational_expression  {
481         $$ = context->addBinaryMathBooleanResult(EOpEqual, $1, $3, @2);
482     }
483     | equality_expression NE_OP relational_expression {
484         $$ = context->addBinaryMathBooleanResult(EOpNotEqual, $1, $3, @2);
485     }
486     ;
487 
488 and_expression
489     : equality_expression { $$ = $1; }
490     | and_expression AMPERSAND equality_expression {
491         ES3_OR_NEWER("&", @2, "bit-wise operator");
492         $$ = context->addBinaryMath(EOpBitwiseAnd, $1, $3, @2);
493     }
494     ;
495 
496 exclusive_or_expression
497     : and_expression { $$ = $1; }
498     | exclusive_or_expression CARET and_expression {
499         ES3_OR_NEWER("^", @2, "bit-wise operator");
500         $$ = context->addBinaryMath(EOpBitwiseXor, $1, $3, @2);
501     }
502     ;
503 
504 inclusive_or_expression
505     : exclusive_or_expression { $$ = $1; }
506     | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
507         ES3_OR_NEWER("|", @2, "bit-wise operator");
508         $$ = context->addBinaryMath(EOpBitwiseOr, $1, $3, @2);
509     }
510     ;
511 
512 logical_and_expression
513     : inclusive_or_expression { $$ = $1; }
514     | logical_and_expression AND_OP inclusive_or_expression {
515         $$ = context->addBinaryMathBooleanResult(EOpLogicalAnd, $1, $3, @2);
516     }
517     ;
518 
519 logical_xor_expression
520     : logical_and_expression { $$ = $1; }
521     | logical_xor_expression XOR_OP logical_and_expression  {
522         $$ = context->addBinaryMathBooleanResult(EOpLogicalXor, $1, $3, @2);
523     }
524     ;
525 
526 logical_or_expression
527     : logical_xor_expression { $$ = $1; }
528     | logical_or_expression OR_OP logical_xor_expression  {
529         $$ = context->addBinaryMathBooleanResult(EOpLogicalOr, $1, $3, @2);
530     }
531     ;
532 
533 conditional_expression
534     : logical_or_expression { $$ = $1; }
535     | logical_or_expression QUESTION expression COLON assignment_expression {
536         $$ = context->addTernarySelection($1, $3, $5, @2);
537     }
538     ;
539 
540 assignment_expression
541     : conditional_expression { $$ = $1; }
542     | unary_expression assignment_operator assignment_expression {
543         $$ = context->addAssign($2, $1, $3, @2);
544     }
545     ;
546 
547 assignment_operator
548     : EQUAL        { $$ = EOpAssign; }
549     | MUL_ASSIGN   { $$ = EOpMulAssign; }
550     | DIV_ASSIGN   { $$ = EOpDivAssign; }
551     | MOD_ASSIGN   {
552         ES3_OR_NEWER("%=", @$, "integer modulus operator");
553         $$ = EOpIModAssign;
554     }
555     | ADD_ASSIGN   { $$ = EOpAddAssign; }
556     | SUB_ASSIGN   { $$ = EOpSubAssign; }
557     | LEFT_ASSIGN {
558         ES3_OR_NEWER("<<=", @$, "bit-wise operator");
559         $$ = EOpBitShiftLeftAssign;
560     }
561     | RIGHT_ASSIGN {
562         ES3_OR_NEWER(">>=", @$, "bit-wise operator");
563         $$ = EOpBitShiftRightAssign;
564     }
565     | AND_ASSIGN {
566         ES3_OR_NEWER("&=", @$, "bit-wise operator");
567         $$ = EOpBitwiseAndAssign;
568     }
569     | XOR_ASSIGN {
570         ES3_OR_NEWER("^=", @$, "bit-wise operator");
571         $$ = EOpBitwiseXorAssign;
572     }
573     | OR_ASSIGN {
574         ES3_OR_NEWER("|=", @$, "bit-wise operator");
575         $$ = EOpBitwiseOrAssign;
576     }
577     ;
578 
579 expression
580     : assignment_expression {
581         $$ = $1;
582     }
583     | expression COMMA assignment_expression {
584         $$ = context->addComma($1, $3, @2);
585     }
586     ;
587 
588 constant_expression
589     : conditional_expression {
590         context->checkIsConst($1);
591         $$ = $1;
592     }
593     ;
594 
595 enter_struct
596     : IDENTIFIER LEFT_BRACE {
597         context->enterStructDeclaration(@1, ImmutableString($1.string));
598         $$ = $1;
599     }
600     ;
601 
602 declaration
603     : function_prototype SEMICOLON {
604         $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
605     }
606     | init_declarator_list SEMICOLON {
607         $$ = $1.intermDeclaration;
608     }
609     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
610         context->parseDefaultPrecisionQualifier($2, $3, @1);
611         $$ = nullptr;
612     }
613     | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON {
614         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
615         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, kEmptyImmutableString, @$, NULL, @$);
616     }
617     | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
618         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
619         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, NULL, @$);
620     }
621     | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON {
622         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
623         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, $7, @6);
624     }
625     | type_qualifier SEMICOLON {
626         context->parseGlobalLayoutQualifier(*$1);
627         $$ = nullptr;
628     }
629     | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant or precise
630     {
631         $$ = context->parseGlobalQualifierDeclaration(*$1, @2, ImmutableString($2.string), $2.symbol);
632     }
633     ;
634 
635 function_prototype
636     : function_declarator RIGHT_PAREN  {
637         $$.function = context->parseFunctionDeclarator(@2, $1);
638         context->exitFunctionDeclaration();
639     }
640     ;
641 
642 function_declarator
643     : function_header {
644         $$ = $1;
645     }
646     | function_header_with_parameters {
647         $$ = $1;
648     }
649     ;
650 
651 
652 function_header_with_parameters
653     : function_header parameter_declaration {
654         // Add the parameter
655         $$ = $1;
656         if ($2.type->getBasicType() != EbtVoid)
657         {
658             $1->addParameter($2.createVariable(&context->symbolTable));
659         }
660     }
661     | function_header_with_parameters COMMA parameter_declaration {
662         $$ = $1;
663         // Only first parameter of one-parameter functions can be void
664         // The check for named parameters not being void is done in parameter_declarator
665         if ($3.type->getBasicType() == EbtVoid)
666         {
667             // This parameter > first is void
668             context->error(@2, "cannot be a parameter type except for '(void)'", "void");
669         }
670         else
671         {
672             $1->addParameter($3.createVariable(&context->symbolTable));
673         }
674     }
675     ;
676 
677 function_header
678     : fully_specified_type IDENTIFIER LEFT_PAREN {
679         $$ = context->parseFunctionHeader($1, ImmutableString($2.string), @2);
680 
681         context->symbolTable.push();
682         context->enterFunctionDeclaration();
683     }
684     ;
685 
686 parameter_declarator
687     // Type + name
688     : type_specifier identifier {
689         $$ = context->parseParameterDeclarator($1, ImmutableString($2.string), @2);
690     }
691     | type_specifier identifier array_specifier {
692         $$ = context->parseParameterArrayDeclarator(ImmutableString($2.string), @2, *($3), @3, &$1);
693     }
694     ;
695 
696 parameter_declaration
697     : type_qualifier parameter_declarator {
698         $$ = $2;
699         context->checkIsParameterQualifierValid(@2, *$1, $2.type);
700     }
701     | parameter_declarator {
702         $$ = $1;
703         $$.type->setQualifier(EvqIn);
704     }
705     | type_qualifier parameter_type_specifier {
706         $$ = $2;
707         context->checkIsParameterQualifierValid(@2, *$1, $2.type);
708     }
709     | parameter_type_specifier {
710         $$ = $1;
711         $$.type->setQualifier(EvqIn);
712     }
713     ;
714 
715 parameter_type_specifier
716     : type_specifier {
717         TParameter param = { 0, new TType($1) };
718         $$ = param;
719     }
720     ;
721 
722 init_declarator_list
723     : single_declaration {
724         $$ = $1;
725     }
726     | init_declarator_list COMMA identifier {
727         $$ = $1;
728         context->parseDeclarator($$.type, @3, ImmutableString($3.string), $$.intermDeclaration);
729     }
730     | init_declarator_list COMMA identifier array_specifier {
731         $$ = $1;
732         context->parseArrayDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), $$.intermDeclaration);
733     }
734     | init_declarator_list COMMA identifier array_specifier EQUAL initializer {
735         ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)");
736         $$ = $1;
737         context->parseArrayInitDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), @5, $6, $$.intermDeclaration);
738     }
739     | init_declarator_list COMMA identifier EQUAL initializer {
740         $$ = $1;
741         context->parseInitDeclarator($$.type, @3, ImmutableString($3.string), @4, $5, $$.intermDeclaration);
742     }
743     ;
744 
745 single_declaration
746     : fully_specified_type {
747         $$.type = $1;
748         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, kEmptyImmutableString);
749     }
750     | fully_specified_type identifier {
751         $$.type = $1;
752         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, ImmutableString($2.string));
753     }
754     | fully_specified_type identifier array_specifier {
755         $$.type = $1;
756         $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3));
757     }
758     | fully_specified_type identifier array_specifier EQUAL initializer {
759         ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)");
760         $$.type = $1;
761         $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3), @4, $5);
762     }
763     | fully_specified_type identifier EQUAL initializer {
764         $$.type = $1;
765         $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, ImmutableString($2.string), @3, $4);
766     }
767     ;
768 
769 fully_specified_type
770     : type_specifier {
771         context->addFullySpecifiedType(&$1);
772         $$ = $1;
773     }
774     | type_qualifier type_specifier {
775         $$ = context->addFullySpecifiedType(*$1, $2);
776     }
777     ;
778 
779 interpolation_qualifier
780     : SMOOTH {
781         $$ = EvqSmooth;
782     }
783     | FLAT {
784         $$ = EvqFlat;
785     }
786     | NOPERSPECTIVE {
787         if (!context->checkCanUseExtension(@1, TExtension::NV_shader_noperspective_interpolation))
788         {
789             context->error(@1, "unsupported interpolation qualifier", "noperspective");
790         }
791         $$ = EvqNoPerspective;
792     }
793     ;
794 
795 type_qualifier
796     : single_type_qualifier {
797         $$ = context->createTypeQualifierBuilder(@1);
798         $$->appendQualifier($1);
799     }
800     | type_qualifier single_type_qualifier {
801         $$ = $1;
802         $$->appendQualifier($2);
803     }
804     ;
805 
806 invariant_qualifier
807     : INVARIANT {
808         // empty
809     }
810     ;
811 
812 precise_qualifier
813     : PRECISE {
814         // empty
815     }
816     ;
817 
818 single_type_qualifier
819     : storage_qualifier {
820         context->checkLocalVariableConstStorageQualifier(*$1);
821         $$ = $1;
822     }
823     | layout_qualifier {
824         context->checkIsAtGlobalLevel(@1, "layout");
825         $$ = new TLayoutQualifierWrapper($1, @1);
826     }
827     | precision_qualifier {
828         $$ = new TPrecisionQualifierWrapper($1, @1);
829     }
830     | interpolation_qualifier {
831         $$ = new TInterpolationQualifierWrapper($1, @1);
832     }
833     | invariant_qualifier {
834         context->checkIsAtGlobalLevel(@1, "invariant");
835         $$ = new TInvariantQualifierWrapper(@1);
836     }
837     | precise_qualifier {
838         $$ = new TPreciseQualifierWrapper(@1);
839     }
840     ;
841 
842 
843 storage_qualifier
844     :
845     ATTRIBUTE {
846         VERTEX_ONLY("attribute", @1);
847         ES2_ONLY("attribute", @1);
848         $$ = context->parseGlobalStorageQualifier(EvqAttribute, @1);
849     }
850     | VARYING {
851         ES2_ONLY("varying", @1);
852         $$ = context->parseVaryingQualifier(@1);
853     }
854     | CONST_QUAL {
855         $$ = new TStorageQualifierWrapper(EvqConst, @1);
856     }
857     | IN_QUAL {
858         $$ = context->parseInQualifier(@1);
859     }
860     | OUT_QUAL {
861         $$ = context->parseOutQualifier(@1);
862     }
863     | INOUT_QUAL {
864         $$ = context->parseInOutQualifier(@1);
865     }
866     | CENTROID {
867         ES3_OR_NEWER("centroid", @1, "storage qualifier");
868         $$ = new TStorageQualifierWrapper(EvqCentroid, @1);
869     }
870     | UNIFORM {
871         $$ = context->parseGlobalStorageQualifier(EvqUniform, @1);
872     }
873     | BUFFER {
874         ES3_1_ONLY("buffer", @1, "storage qualifier");
875         $$ = context->parseGlobalStorageQualifier(EvqBuffer, @1);
876     }
877     | READONLY {
878         $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1);
879     }
880     | WRITEONLY {
881         $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1);
882     }
883     | COHERENT {
884         $$ = new TMemoryQualifierWrapper(EvqCoherent, @1);
885     }
886     | RESTRICT {
887         $$ = new TMemoryQualifierWrapper(EvqRestrict, @1);
888     }
889     | VOLATILE {
890         $$ = new TMemoryQualifierWrapper(EvqVolatile, @1);
891     }
892     | SHARED {
893         COMPUTE_ONLY("shared", @1);
894         $$ = context->parseGlobalStorageQualifier(EvqShared, @1);
895     }
896     | SAMPLE {
897         ES3_OR_NEWER("sample", @1, "storage qualifier");
898         $$ = new TStorageQualifierWrapper(EvqSample, @1);
899     }
900     ;
901 
902 type_specifier
903     : type_specifier_no_prec {
904         $$ = $1;
905         $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType());
906     }
907     ;
908 
909 precision_qualifier
910     : HIGH_PRECISION {
911         $$ = EbpHigh;
912     }
913     | MEDIUM_PRECISION {
914         $$ = EbpMedium;
915     }
916     | LOW_PRECISION  {
917         $$ = EbpLow;
918     }
919     ;
920 
921 layout_qualifier
922     : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
923         ES3_OR_NEWER("layout", @1, "qualifier");
924         $$ = $3;
925     }
926     ;
927 
928 layout_qualifier_id_list
929     : layout_qualifier_id {
930         $$ = $1;
931     }
932     | layout_qualifier_id_list COMMA layout_qualifier_id {
933         $$ = context->joinLayoutQualifiers($1, $3, @3);
934     }
935     ;
936 
937 layout_qualifier_id
938     : IDENTIFIER {
939         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1);
940     }
941     | IDENTIFIER EQUAL INTCONSTANT {
942         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
943     }
944     | IDENTIFIER EQUAL UINTCONSTANT {
945         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
946     }
947     | SHARED {
948         $$ = context->parseLayoutQualifier(ImmutableString("shared"), @1);
949     }
950     ;
951 
952 type_specifier_no_prec
953     : type_specifier_nonarray {
954         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
955     }
956     | type_specifier_nonarray array_specifier {
957         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
958         $$.setArraySizes($2);
959     }
960     ;
961 
962 array_specifier
963     : LEFT_BRACKET RIGHT_BRACKET {
964         ES3_OR_NEWER("[]", @1, "implicitly sized array");
965         $$ = new TVector<unsigned int>();
966         $$->push_back(0u);
967     }
968     | LEFT_BRACKET constant_expression RIGHT_BRACKET {
969         $$ = new TVector<unsigned int>();
970         unsigned int size = context->checkIsValidArraySize(@1, $2);
971         // Make the type an array even if size check failed.
972         // This ensures useless error messages regarding a variable's non-arrayness won't follow.
973         $$->push_back(size);
974     }
975     | array_specifier LEFT_BRACKET RIGHT_BRACKET {
976         ES3_1_ONLY("[]", @2, "arrays of arrays");
977         $$ = $1;
978         $$->insert($$->begin(), 0u);
979     }
980     | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
981         ES3_1_ONLY("[]", @2, "arrays of arrays");
982         $$ = $1;
983         unsigned int size = context->checkIsValidArraySize(@2, $3);
984         // Make the type an array even if size check failed.
985         // This ensures useless error messages regarding a variable's non-arrayness won't follow.
986         $$->insert($$->begin(), size);
987     }
988     ;
989 
990 type_specifier_nonarray
991     : VOID_TYPE {
992         $$.initialize(EbtVoid, @1);
993     }
994     | FLOAT_TYPE {
995         $$.initialize(EbtFloat, @1);
996     }
997     | INT_TYPE {
998         $$.initialize(EbtInt, @1);
999     }
1000     | UINT_TYPE {
1001         $$.initialize(EbtUInt, @1);
1002     }
1003     | BOOL_TYPE {
1004         $$.initialize(EbtBool, @1);
1005     }
1006     | VEC2 {
1007         $$.initialize(EbtFloat, @1);
1008         $$.setAggregate(2);
1009     }
1010     | VEC3 {
1011         $$.initialize(EbtFloat, @1);
1012         $$.setAggregate(3);
1013     }
1014     | VEC4 {
1015         $$.initialize(EbtFloat, @1);
1016         $$.setAggregate(4);
1017     }
1018     | BVEC2 {
1019         $$.initialize(EbtBool, @1);
1020         $$.setAggregate(2);
1021     }
1022     | BVEC3 {
1023         $$.initialize(EbtBool, @1);
1024         $$.setAggregate(3);
1025     }
1026     | BVEC4 {
1027         $$.initialize(EbtBool, @1);
1028         $$.setAggregate(4);
1029     }
1030     | IVEC2 {
1031         $$.initialize(EbtInt, @1);
1032         $$.setAggregate(2);
1033     }
1034     | IVEC3 {
1035         $$.initialize(EbtInt, @1);
1036         $$.setAggregate(3);
1037     }
1038     | IVEC4 {
1039         $$.initialize(EbtInt, @1);
1040         $$.setAggregate(4);
1041     }
1042     | UVEC2 {
1043         $$.initialize(EbtUInt, @1);
1044         $$.setAggregate(2);
1045     }
1046     | UVEC3 {
1047         $$.initialize(EbtUInt, @1);
1048         $$.setAggregate(3);
1049     }
1050     | UVEC4 {
1051         $$.initialize(EbtUInt, @1);
1052         $$.setAggregate(4);
1053     }
1054     | MATRIX2 {
1055         $$.initialize(EbtFloat, @1);
1056         $$.setMatrix(2, 2);
1057     }
1058     | MATRIX3 {
1059         $$.initialize(EbtFloat, @1);
1060         $$.setMatrix(3, 3);
1061     }
1062     | MATRIX4 {
1063         $$.initialize(EbtFloat, @1);
1064         $$.setMatrix(4, 4);
1065     }
1066     | MATRIX2x3 {
1067         $$.initialize(EbtFloat, @1);
1068         $$.setMatrix(2, 3);
1069     }
1070     | MATRIX3x2 {
1071         $$.initialize(EbtFloat, @1);
1072         $$.setMatrix(3, 2);
1073     }
1074     | MATRIX2x4 {
1075         $$.initialize(EbtFloat, @1);
1076         $$.setMatrix(2, 4);
1077     }
1078     | MATRIX4x2 {
1079         $$.initialize(EbtFloat, @1);
1080         $$.setMatrix(4, 2);
1081     }
1082     | MATRIX3x4 {
1083         $$.initialize(EbtFloat, @1);
1084         $$.setMatrix(3, 4);
1085     }
1086     | MATRIX4x3 {
1087         $$.initialize(EbtFloat, @1);
1088         $$.setMatrix(4, 3);
1089     }
1090     | YUVCSCSTANDARDEXT {
1091         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
1092         {
1093             context->error(@1, "unsupported type", "yuvCscStandardEXT");
1094         }
1095         $$.initialize(EbtYuvCscStandardEXT, @1);
1096     }
1097     | SAMPLER2D {
1098         $$.initialize(EbtSampler2D, @1);
1099     }
1100     | SAMPLER3D {
1101         $$.initialize(EbtSampler3D, @1);
1102     }
1103     | SAMPLERCUBE {
1104         $$.initialize(EbtSamplerCube, @1);
1105     }
1106     | SAMPLER2DARRAY {
1107         $$.initialize(EbtSampler2DArray, @1);
1108     }
1109     | SAMPLER2DMS {
1110         $$.initialize(EbtSampler2DMS, @1);
1111     }
1112     | SAMPLER2DMSARRAY {
1113         $$.initialize(EbtSampler2DMSArray, @1);
1114     }
1115     | SAMPLERCUBEARRAYOES {
1116         if (context->getShaderVersion() < 320
1117         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1118         {
1119             context->error(@1, "unsupported type", "__samplerCubeArray");
1120         }
1121         $$.initialize(EbtSamplerCubeArray, @1);
1122     }
1123     | SAMPLERCUBEARRAYEXT {
1124         if (context->getShaderVersion() < 320
1125         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1126         {
1127             context->error(@1, "unsupported type", "__samplerCubeArray");
1128         }
1129         $$.initialize(EbtSamplerCubeArray, @1);
1130     }
1131     | SAMPLERBUFFER {
1132         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1133                                                            TExtension::EXT_texture_buffer } };
1134         if (context->getShaderVersion() < 320
1135         && !context->checkCanUseOneOfExtensions(@1, extensions))
1136         {
1137             context->error(@1, "unsupported type", "__samplerBuffer");
1138         }
1139         $$.initialize(EbtSamplerBuffer, @1);
1140     }
1141     | ISAMPLER2D {
1142         $$.initialize(EbtISampler2D, @1);
1143     }
1144     | ISAMPLER3D {
1145         $$.initialize(EbtISampler3D, @1);
1146     }
1147     | ISAMPLERCUBE {
1148         $$.initialize(EbtISamplerCube, @1);
1149     }
1150     | ISAMPLER2DARRAY {
1151         $$.initialize(EbtISampler2DArray, @1);
1152     }
1153     | ISAMPLER2DMS {
1154         $$.initialize(EbtISampler2DMS, @1);
1155     }
1156     | ISAMPLER2DMSARRAY {
1157         $$.initialize(EbtISampler2DMSArray, @1);
1158     }
1159     | ISAMPLERCUBEARRAYOES {
1160         if (context->getShaderVersion() < 320
1161         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1162         {
1163             context->error(@1, "unsupported type", "__isamplerCubeArray");
1164         }
1165         $$.initialize(EbtISamplerCubeArray, @1);
1166     }
1167     | ISAMPLERCUBEARRAYEXT {
1168         if (context->getShaderVersion() < 320
1169         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1170         {
1171             context->error(@1, "unsupported type", "__isamplerCubeArray");
1172         }
1173         $$.initialize(EbtISamplerCubeArray, @1);
1174     }
1175     | ISAMPLERBUFFER {
1176         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1177                                                            TExtension::EXT_texture_buffer } };
1178         if (context->getShaderVersion() < 320
1179         && !context->checkCanUseOneOfExtensions(@1, extensions))
1180         {
1181             context->error(@1, "unsupported type", "__isamplerBuffer");
1182         }
1183         $$.initialize(EbtISamplerBuffer, @1);
1184     }
1185     | USAMPLER2D {
1186         $$.initialize(EbtUSampler2D, @1);
1187     }
1188     | USAMPLER3D {
1189         $$.initialize(EbtUSampler3D, @1);
1190     }
1191     | USAMPLERCUBE {
1192         $$.initialize(EbtUSamplerCube, @1);
1193     }
1194     | USAMPLER2DARRAY {
1195         $$.initialize(EbtUSampler2DArray, @1);
1196     }
1197     | USAMPLER2DMS {
1198         $$.initialize(EbtUSampler2DMS, @1);
1199     }
1200     | USAMPLER2DMSARRAY {
1201         $$.initialize(EbtUSampler2DMSArray, @1);
1202     }
1203     | USAMPLERCUBEARRAYOES {
1204         if (context->getShaderVersion() < 320
1205         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1206         {
1207             context->error(@1, "unsupported type", "__usamplerCubeArray");
1208         }
1209         $$.initialize(EbtUSamplerCubeArray, @1);
1210     }
1211     | USAMPLERCUBEARRAYEXT {
1212         if (context->getShaderVersion() < 320
1213         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1214         {
1215             context->error(@1, "unsupported type", "__usamplerCubeArray");
1216         }
1217         $$.initialize(EbtUSamplerCubeArray, @1);
1218     }
1219     | USAMPLERBUFFER {
1220         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1221                                                            TExtension::EXT_texture_buffer } };
1222         if (context->getShaderVersion() < 320
1223         && !context->checkCanUseOneOfExtensions(@1, extensions))
1224         {
1225             context->error(@1, "unsupported type", "__usamplerBuffer");
1226         }
1227         $$.initialize(EbtUSamplerBuffer, @1);
1228     }
1229     | SAMPLER2DSHADOW {
1230         $$.initialize(EbtSampler2DShadow, @1);
1231     }
1232     | SAMPLERCUBESHADOW {
1233         $$.initialize(EbtSamplerCubeShadow, @1);
1234     }
1235     | SAMPLER2DARRAYSHADOW {
1236         $$.initialize(EbtSampler2DArrayShadow, @1);
1237     }
1238     | SAMPLERCUBEARRAYSHADOWOES {
1239         if (context->getShaderVersion() < 320
1240         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1241         {
1242             context->error(@1, "unsupported type", "__samplerCubeArrayShadow");
1243         }
1244         $$.initialize(EbtSamplerCubeArrayShadow, @1);
1245     }
1246     | SAMPLERCUBEARRAYSHADOWEXT {
1247         if (context->getShaderVersion() < 320
1248         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1249         {
1250             context->error(@1, "unsupported type", "__samplerCubeArrayShadow");
1251         }
1252         $$.initialize(EbtSamplerCubeArrayShadow, @1);
1253     }
1254     | SAMPLERVIDEOWEBGL {
1255         if (!context->checkCanUseExtension(@1, TExtension::WEBGL_video_texture))
1256         {
1257             context->error(@1, "unsupported type", "samplerVideoWEBGL");
1258         }
1259         $$.initialize(EbtSamplerVideoWEBGL, @1);
1260     }
1261     | SAMPLER_EXTERNAL_OES {
1262         constexpr std::array<TExtension, 3u> extensions{ { TExtension::NV_EGL_stream_consumer_external,
1263                                                            TExtension::OES_EGL_image_external_essl3,
1264                                                            TExtension::OES_EGL_image_external } };
1265         if (!context->checkCanUseOneOfExtensions(@1, extensions))
1266         {
1267             context->error(@1, "unsupported type", "samplerExternalOES");
1268         }
1269         $$.initialize(EbtSamplerExternalOES, @1);
1270     }
1271     | SAMPLEREXTERNAL2DY2YEXT {
1272         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
1273         {
1274             context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT");
1275         }
1276         $$.initialize(EbtSamplerExternal2DY2YEXT, @1);
1277     }
1278     | SAMPLER2DRECT {
1279         if (!context->checkCanUseExtension(@1, TExtension::ARB_texture_rectangle))
1280         {
1281             context->error(@1, "unsupported type", "sampler2DRect");
1282         }
1283         $$.initialize(EbtSampler2DRect, @1);
1284     }
1285     | IMAGE2D {
1286         $$.initialize(EbtImage2D, @1);
1287     }
1288     | IIMAGE2D {
1289         $$.initialize(EbtIImage2D, @1);
1290     }
1291     | UIMAGE2D {
1292         $$.initialize(EbtUImage2D, @1);
1293     }
1294     | IMAGE3D {
1295         $$.initialize(EbtImage3D, @1);
1296     }
1297     | IIMAGE3D {
1298         $$.initialize(EbtIImage3D, @1);
1299     }
1300     | UIMAGE3D {
1301         $$.initialize(EbtUImage3D, @1);
1302     }
1303     | IMAGE2DARRAY {
1304         $$.initialize(EbtImage2DArray, @1);
1305     }
1306     | IIMAGE2DARRAY {
1307         $$.initialize(EbtIImage2DArray, @1);
1308     }
1309     | UIMAGE2DARRAY {
1310         $$.initialize(EbtUImage2DArray, @1);
1311     }
1312     | IMAGECUBE {
1313         $$.initialize(EbtImageCube, @1);
1314     }
1315     | IIMAGECUBE {
1316         $$.initialize(EbtIImageCube, @1);
1317     }
1318     | UIMAGECUBE {
1319         $$.initialize(EbtUImageCube, @1);
1320     }
1321     | IMAGECUBEARRAYOES {
1322         if (context->getShaderVersion() < 320
1323         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1324         {
1325             context->error(@1, "unsupported type", "__imageCubeArray");
1326         }
1327         $$.initialize(EbtImageCubeArray, @1);
1328     }
1329     | IMAGECUBEARRAYEXT {
1330         if (context->getShaderVersion() < 320
1331         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1332         {
1333             context->error(@1, "unsupported type", "__imageCubeArray");
1334         }
1335         $$.initialize(EbtImageCubeArray, @1);
1336     }
1337     | IIMAGECUBEARRAYOES {
1338         if (context->getShaderVersion() < 320
1339         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1340         {
1341             context->error(@1, "unsupported type", "__iimageCubeArray");
1342         }
1343         $$.initialize(EbtIImageCubeArray, @1);
1344     }
1345     | IIMAGECUBEARRAYEXT {
1346         if (context->getShaderVersion() < 320
1347         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1348         {
1349             context->error(@1, "unsupported type", "__iimageCubeArray");
1350         }
1351         $$.initialize(EbtIImageCubeArray, @1);
1352     }
1353     | UIMAGECUBEARRAYOES {
1354        if (context->getShaderVersion() < 320
1355        && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1356         {
1357             context->error(@1, "unsupported type", "__uimageCubeArray");
1358         }
1359         $$.initialize(EbtUImageCubeArray, @1);
1360     }
1361     | UIMAGECUBEARRAYEXT {
1362        if (context->getShaderVersion() < 320
1363        && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1364         {
1365             context->error(@1, "unsupported type", "__uimageCubeArray");
1366         }
1367         $$.initialize(EbtUImageCubeArray, @1);
1368     }
1369     | IMAGEBUFFER {
1370         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1371                                                            TExtension::EXT_texture_buffer } };
1372         if (context->getShaderVersion() < 320
1373         && !context->checkCanUseOneOfExtensions(@1, extensions))
1374         {
1375             context->error(@1, "unsupported type", "__imageBuffer");
1376         }
1377         $$.initialize(EbtImageBuffer, @1);
1378     }
1379     | IIMAGEBUFFER {
1380         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1381                                                            TExtension::EXT_texture_buffer } };
1382         if (context->getShaderVersion() < 320
1383         && !context->checkCanUseOneOfExtensions(@1, extensions))
1384         {
1385             context->error(@1, "unsupported type", "__iimageBuffer");
1386         }
1387         $$.initialize(EbtIImageBuffer, @1);
1388     }
1389     | UIMAGEBUFFER {
1390         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1391                                                            TExtension::EXT_texture_buffer } };
1392         if (context->getShaderVersion() < 320
1393         && !context->checkCanUseOneOfExtensions(@1, extensions))
1394         {
1395             context->error(@1, "unsupported type", "__uimageBuffer");
1396         }
1397         $$.initialize(EbtUImageBuffer, @1);
1398     }
1399     | ATOMICUINT {
1400         $$.initialize(EbtAtomicCounter, @1);
1401     }
1402     | struct_specifier {
1403         $$ = $1;
1404     }
1405     | TYPE_NAME {
1406         // This is for user defined type names. The lexical phase looked up the type.
1407         const TStructure *structure = static_cast<const TStructure*>($1.symbol);
1408         $$.initializeStruct(structure, false, @1);
1409     }
1410     ;
1411 
1412 struct_specifier
1413     : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, ImmutableString($2.string)); } struct_declaration_list RIGHT_BRACE {
1414         $$ = context->addStructure(@1, @2, ImmutableString($2.string), $5);
1415     }
1416     | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, kEmptyImmutableString); } struct_declaration_list RIGHT_BRACE {
1417         $$ = context->addStructure(@1, @$, kEmptyImmutableString, $4);
1418     }
1419     ;
1420 
1421 struct_declaration_list
1422     : struct_declaration {
1423         $$ = context->addStructFieldList($1, @1);
1424     }
1425     | struct_declaration_list struct_declaration {
1426         $$ = context->combineStructFieldLists($1, $2, @2);
1427     }
1428     ;
1429 
1430 struct_declaration
1431     : type_specifier struct_declarator_list SEMICOLON {
1432         $$ = context->addStructDeclaratorList($1, $2);
1433     }
1434     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
1435         // ES3 Only, but errors should be handled elsewhere
1436         $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3);
1437     }
1438     ;
1439 
1440 struct_declarator_list
1441     : struct_declarator {
1442         $$ = new TDeclaratorList();
1443         $$->push_back($1);
1444     }
1445     | struct_declarator_list COMMA struct_declarator {
1446         $$->push_back($3);
1447     }
1448     ;
1449 
1450 struct_declarator
1451     : identifier {
1452         $$ = context->parseStructDeclarator(ImmutableString($1.string), @1);
1453     }
1454     | identifier array_specifier {
1455         $$ = context->parseStructArrayDeclarator(ImmutableString($1.string), @1, $2);
1456     }
1457     ;
1458 
1459 initializer
1460     : assignment_expression { $$ = $1; }
1461     ;
1462 
1463 declaration_statement
1464     : declaration { $$ = $1; }
1465     ;
1466 
1467 statement
1468     : compound_statement_with_scope { $$ = $1; }
1469     | simple_statement              { $$ = $1; }
1470     ;
1471 
1472 // Grammar Note:  Labeled statements for SWITCH only; 'goto' is not supported.
1473 
1474 simple_statement
1475     : declaration_statement { $$ = $1; }
1476     | expression_statement  { $$ = $1; }
1477     | selection_statement   { $$ = $1; }
1478     | switch_statement      { $$ = $1; }
1479     | case_label            { $$ = $1; }
1480     | iteration_statement   { $$ = $1; }
1481     | jump_statement        { $$ = $1; }
1482     ;
1483 
1484 compound_statement_with_scope
1485     : LEFT_BRACE RIGHT_BRACE {
1486         $$ = new TIntermBlock();
1487         $$->setLine(@$);
1488     }
1489     | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
1490         $3->setLine(@$);
1491         $$ = $3;
1492     }
1493     ;
1494 
1495 statement_no_new_scope
1496     : compound_statement_no_new_scope { $$ = $1; }
1497     | simple_statement                { $$ = $1; }
1498     ;
1499 
1500 statement_with_scope
1501     : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
1502     | { context->symbolTable.push(); } simple_statement                { context->symbolTable.pop(); $$ = $2; }
1503     ;
1504 
1505 compound_statement_no_new_scope
1506     // Statement that doesn't create a new scope for iteration_statement, function definition (scope is created for parameters)
1507     : LEFT_BRACE RIGHT_BRACE {
1508         $$ = new TIntermBlock();
1509         $$->setLine(@$);
1510     }
1511     | LEFT_BRACE statement_list RIGHT_BRACE {
1512         $2->setLine(@$);
1513         $$ = $2;
1514     }
1515     ;
1516 
1517 statement_list
1518     : statement {
1519         $$ = new TIntermBlock();
1520         context->appendStatement($$, $1);
1521     }
1522     | statement_list statement {
1523         $$ = $1;
1524         context->appendStatement($$, $2);
1525     }
1526     ;
1527 
1528 expression_statement
1529     : SEMICOLON  { $$ = context->addEmptyStatement(@$); }
1530     | expression SEMICOLON  { $$ = $1; }
1531     ;
1532 
1533 selection_statement
1534     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
1535         $$ = context->addIfElse($3, $5, @1);
1536     }
1537     ;
1538 
1539 selection_rest_statement
1540     : statement_with_scope ELSE statement_with_scope {
1541         $$.node1 = $1;
1542         $$.node2 = $3;
1543     }
1544     | statement_with_scope {
1545         $$.node1 = $1;
1546         $$.node2 = nullptr;
1547     }
1548     ;
1549 
1550 // Note that we've diverged from the spec grammar here a bit for the sake of simplicity.
1551 // We're reusing compound_statement_with_scope instead of having separate rules for switch.
1552 switch_statement
1553     : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement_with_scope {
1554         $$ = context->addSwitch($3, $6, @1);
1555         context->decrSwitchNestingLevel();
1556     }
1557     ;
1558 
1559 case_label
1560     : CASE constant_expression COLON {
1561         $$ = context->addCase($2, @1);
1562     }
1563     | DEFAULT COLON {
1564         $$ = context->addDefault(@1);
1565     }
1566     ;
1567 
1568 condition
1569     : expression {
1570         $$ = $1;
1571         context->checkIsScalarBool($1->getLine(), $1);
1572     }
1573     | fully_specified_type identifier EQUAL initializer {
1574         $$ = context->addConditionInitializer($1, ImmutableString($2.string), $4, @2);
1575     }
1576     ;
1577 
1578 iteration_statement
1579     : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } condition RIGHT_PAREN statement_no_new_scope {
1580         context->symbolTable.pop();
1581         $$ = context->addLoop(ELoopWhile, 0, $4, 0, $6, @1);
1582         context->decrLoopNestingLevel();
1583     }
1584     | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
1585         $$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
1586         context->decrLoopNestingLevel();
1587     }
1588     | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
1589         context->symbolTable.pop();
1590         $$ = context->addLoop(ELoopFor, $4, $5.node1, reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
1591         context->decrLoopNestingLevel();
1592     }
1593     ;
1594 
1595 for_init_statement
1596     : expression_statement {
1597         $$ = $1;
1598     }
1599     | declaration_statement {
1600         $$ = $1;
1601     }
1602     ;
1603 
1604 conditionopt
1605     : condition {
1606         $$ = $1;
1607     }
1608     | /* May be null */ {
1609         $$ = nullptr;
1610     }
1611     ;
1612 
1613 for_rest_statement
1614     : conditionopt SEMICOLON {
1615         $$.node1 = $1;
1616         $$.node2 = 0;
1617     }
1618     | conditionopt SEMICOLON expression  {
1619         $$.node1 = $1;
1620         $$.node2 = $3;
1621     }
1622     ;
1623 
1624 jump_statement
1625     : CONTINUE SEMICOLON {
1626         $$ = context->addBranch(EOpContinue, @1);
1627     }
1628     | BREAK SEMICOLON {
1629         $$ = context->addBranch(EOpBreak, @1);
1630     }
1631     | RETURN SEMICOLON {
1632         $$ = context->addBranch(EOpReturn, @1);
1633     }
1634     | RETURN expression SEMICOLON {
1635         $$ = context->addBranch(EOpReturn, $2, @1);
1636     }
1637     | DISCARD SEMICOLON {
1638         $$ = context->addBranch(EOpKill, @1);
1639     }
1640     ;
1641 
1642 // Grammar Note:  No 'goto'.  Gotos are not supported.
1643 
1644 translation_unit
1645     : external_declaration {
1646         $$ = new TIntermBlock();
1647         $$->setLine(@$);
1648         $$->appendStatement($1);
1649         context->setTreeRoot($$);
1650     }
1651     | translation_unit external_declaration {
1652         $$->appendStatement($2);
1653     }
1654     ;
1655 
1656 external_declaration
1657     : function_definition {
1658         $$ = $1;
1659     }
1660     | declaration {
1661         $$ = $1;
1662     }
1663     ;
1664 
1665 function_definition
1666     : function_prototype {
1667         context->parseFunctionDefinitionHeader(@1, $1.function, &($1.intermFunctionPrototype));
1668     }
1669     compound_statement_no_new_scope {
1670         $$ = context->addFunctionDefinition($1.intermFunctionPrototype, $3, @1);
1671     }
1672     ;
1673 
1674 %%
1675 
1676 int glslang_parse(TParseContext* context) {
1677     return yyparse(context, context->getScanner());
1678 }
1679