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