• 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 #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_OR_NEWER(TOKEN, LINE, REASON) do {  \
155     if (context->getShaderVersion() < 310) {  \
156         context->error(LINE, REASON " supported in GLSL ES 3.10 and above 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 PATCH
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 array_specifier SEMICOLON {
622         ES3_OR_NEWER(ImmutableString($2.string), @1, "interface blocks");
623         $$ = context->addInterfaceBlock(*$1, @2, ImmutableString($2.string), $3, ImmutableString($5.string), @5, $6, @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         else
661         {
662             // Remember that void was seen, so error can be generated if another parameter is seen.
663             $1->setHasVoidParameter();
664         }
665     }
666     | function_header_with_parameters COMMA parameter_declaration {
667         $$ = $1;
668         // Only first parameter of one-parameter functions can be void
669         // The check for named parameters not being void is done in parameter_declarator
670         if ($3.type->getBasicType() == EbtVoid)
671         {
672             // This parameter > first is void
673             context->error(@2, "cannot be a parameter type except for '(void)'", "void");
674         }
675         else
676         {
677             if ($1->hasVoidParameter())
678             {
679                 // Only first parameter of one-parameter functions can be void.  This check prevents
680                 // (void, non_void) parameters.
681                 context->error(@2, "cannot be a parameter type except for '(void)'", "void");
682             }
683             $1->addParameter($3.createVariable(&context->symbolTable));
684         }
685     }
686     ;
687 
688 function_header
689     : fully_specified_type IDENTIFIER LEFT_PAREN {
690         $$ = context->parseFunctionHeader($1, ImmutableString($2.string), @2);
691 
692         context->symbolTable.push();
693         context->enterFunctionDeclaration();
694     }
695     ;
696 
697 parameter_declarator
698     // Type + name
699     : type_specifier identifier {
700         $$ = context->parseParameterDeclarator($1, ImmutableString($2.string), @2);
701     }
702     | type_specifier identifier array_specifier {
703         $$ = context->parseParameterArrayDeclarator(ImmutableString($2.string), @2, *($3), @3, &$1);
704     }
705     ;
706 
707 parameter_declaration
708     : type_qualifier parameter_declarator {
709         $$ = $2;
710         context->checkIsParameterQualifierValid(@2, *$1, $2.type);
711     }
712     | parameter_declarator {
713         $$ = $1;
714         $$.type->setQualifier(EvqParamIn);
715     }
716     | type_qualifier parameter_type_specifier {
717         $$ = $2;
718         context->checkIsParameterQualifierValid(@2, *$1, $2.type);
719     }
720     | parameter_type_specifier {
721         $$ = $1;
722         $$.type->setQualifier(EvqParamIn);
723     }
724     ;
725 
726 parameter_type_specifier
727     : type_specifier {
728         TParameter param = { 0, new TType($1) };
729         $$ = param;
730     }
731     ;
732 
733 init_declarator_list
734     : single_declaration {
735         $$ = $1;
736     }
737     | init_declarator_list COMMA identifier {
738         $$ = $1;
739         context->parseDeclarator($$.type, @3, ImmutableString($3.string), $$.intermDeclaration);
740     }
741     | init_declarator_list COMMA identifier array_specifier {
742         $$ = $1;
743         context->parseArrayDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), $$.intermDeclaration);
744     }
745     | init_declarator_list COMMA identifier array_specifier EQUAL initializer {
746         ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)");
747         $$ = $1;
748         context->parseArrayInitDeclarator($$.type, @3, ImmutableString($3.string), @4, *($4), @5, $6, $$.intermDeclaration);
749     }
750     | init_declarator_list COMMA identifier EQUAL initializer {
751         $$ = $1;
752         context->parseInitDeclarator($$.type, @3, ImmutableString($3.string), @4, $5, $$.intermDeclaration);
753     }
754     ;
755 
756 single_declaration
757     : fully_specified_type {
758         $$.type = $1;
759         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, kEmptyImmutableString);
760     }
761     | fully_specified_type identifier {
762         $$.type = $1;
763         $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, ImmutableString($2.string));
764     }
765     | fully_specified_type identifier array_specifier {
766         $$.type = $1;
767         $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3));
768     }
769     | fully_specified_type identifier array_specifier EQUAL initializer {
770         ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)");
771         $$.type = $1;
772         $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, ImmutableString($2.string), @3, *($3), @4, $5);
773     }
774     | fully_specified_type identifier EQUAL initializer {
775         $$.type = $1;
776         $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, ImmutableString($2.string), @3, $4);
777     }
778     ;
779 
780 fully_specified_type
781     : type_specifier {
782         context->addFullySpecifiedType(&$1);
783         $$ = $1;
784     }
785     | type_qualifier type_specifier {
786         $$ = context->addFullySpecifiedType(*$1, $2);
787     }
788     ;
789 
790 interpolation_qualifier
791     : SMOOTH {
792         $$ = EvqSmooth;
793     }
794     | FLAT {
795         $$ = EvqFlat;
796     }
797     | NOPERSPECTIVE {
798         if (!context->checkCanUseExtension(@1, TExtension::NV_shader_noperspective_interpolation))
799         {
800             context->error(@1, "unsupported interpolation qualifier", "noperspective");
801         }
802         $$ = EvqNoPerspective;
803     }
804     ;
805 
806 type_qualifier
807     : single_type_qualifier {
808         $$ = context->createTypeQualifierBuilder(@1);
809         $$->appendQualifier($1);
810     }
811     | type_qualifier single_type_qualifier {
812         $$ = $1;
813         $$->appendQualifier($2);
814     }
815     ;
816 
817 invariant_qualifier
818     : INVARIANT {
819         // empty
820     }
821     ;
822 
823 precise_qualifier
824     : PRECISE {
825         context->markShaderHasPrecise();
826     }
827     ;
828 
829 single_type_qualifier
830     : storage_qualifier {
831         context->checkLocalVariableConstStorageQualifier(*$1);
832         $$ = $1;
833     }
834     | layout_qualifier {
835         context->checkIsAtGlobalLevel(@1, "layout");
836         $$ = new TLayoutQualifierWrapper($1, @1);
837     }
838     | precision_qualifier {
839         $$ = new TPrecisionQualifierWrapper($1, @1);
840     }
841     | interpolation_qualifier {
842         $$ = new TInterpolationQualifierWrapper($1, @1);
843     }
844     | invariant_qualifier {
845         context->checkIsAtGlobalLevel(@1, "invariant");
846         $$ = new TInvariantQualifierWrapper(@1);
847     }
848     | precise_qualifier {
849         $$ = new TPreciseQualifierWrapper(@1);
850     }
851     ;
852 
853 
854 storage_qualifier
855     :
856     ATTRIBUTE {
857         VERTEX_ONLY("attribute", @1);
858         ES2_ONLY("attribute", @1);
859         $$ = context->parseGlobalStorageQualifier(EvqAttribute, @1);
860     }
861     | VARYING {
862         ES2_ONLY("varying", @1);
863         $$ = context->parseVaryingQualifier(@1);
864     }
865     | CONST_QUAL {
866         $$ = new TStorageQualifierWrapper(EvqConst, @1);
867     }
868     | IN_QUAL {
869         $$ = context->parseInQualifier(@1);
870     }
871     | OUT_QUAL {
872         $$ = context->parseOutQualifier(@1);
873     }
874     | INOUT_QUAL {
875         $$ = context->parseInOutQualifier(@1);
876     }
877     | CENTROID {
878         ES3_OR_NEWER("centroid", @1, "storage qualifier");
879         $$ = new TStorageQualifierWrapper(EvqCentroid, @1);
880     }
881     | PATCH {
882         if (context->getShaderVersion() < 320 &&
883             !context->checkCanUseExtension(@1, TExtension::EXT_tessellation_shader))
884         {
885             context->error(@1, "unsupported storage qualifier", "patch");
886         }
887         $$ = new TStorageQualifierWrapper(EvqPatch, @1);
888     }
889     | UNIFORM {
890         $$ = context->parseGlobalStorageQualifier(EvqUniform, @1);
891     }
892     | BUFFER {
893         ES3_1_OR_NEWER("buffer", @1, "storage qualifier");
894         $$ = context->parseGlobalStorageQualifier(EvqBuffer, @1);
895     }
896     | READONLY {
897         $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1);
898     }
899     | WRITEONLY {
900         $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1);
901     }
902     | COHERENT {
903         $$ = new TMemoryQualifierWrapper(EvqCoherent, @1);
904     }
905     | RESTRICT {
906         $$ = new TMemoryQualifierWrapper(EvqRestrict, @1);
907     }
908     | VOLATILE {
909         $$ = new TMemoryQualifierWrapper(EvqVolatile, @1);
910     }
911     | SHARED {
912         COMPUTE_ONLY("shared", @1);
913         $$ = context->parseGlobalStorageQualifier(EvqShared, @1);
914     }
915     | SAMPLE {
916         ES3_OR_NEWER("sample", @1, "storage qualifier");
917         $$ = new TStorageQualifierWrapper(EvqSample, @1);
918     }
919     ;
920 
921 type_specifier
922     : type_specifier_no_prec {
923         $$ = $1;
924         $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType());
925     }
926     ;
927 
928 precision_qualifier
929     : HIGH_PRECISION {
930         $$ = EbpHigh;
931     }
932     | MEDIUM_PRECISION {
933         $$ = EbpMedium;
934     }
935     | LOW_PRECISION  {
936         $$ = EbpLow;
937     }
938     ;
939 
940 layout_qualifier
941     : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
942         context->checkCanUseLayoutQualifier(@1);
943         $$ = $3;
944     }
945     ;
946 
947 layout_qualifier_id_list
948     : layout_qualifier_id {
949         $$ = $1;
950     }
951     | layout_qualifier_id_list COMMA layout_qualifier_id {
952         $$ = context->joinLayoutQualifiers($1, $3, @3);
953     }
954     ;
955 
956 layout_qualifier_id
957     : IDENTIFIER {
958         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1);
959     }
960     | IDENTIFIER EQUAL INTCONSTANT {
961         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
962     }
963     | IDENTIFIER EQUAL UINTCONSTANT {
964         $$ = context->parseLayoutQualifier(ImmutableString($1.string), @1, $3.i, @3);
965     }
966     | SHARED {
967         $$ = context->parseLayoutQualifier(ImmutableString("shared"), @1);
968     }
969     ;
970 
971 type_specifier_no_prec
972     : type_specifier_nonarray {
973         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
974     }
975     | type_specifier_nonarray array_specifier {
976         $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
977         $$.setArraySizes($2);
978     }
979     ;
980 
981 array_specifier
982     : LEFT_BRACKET RIGHT_BRACKET {
983         ES3_OR_NEWER("[]", @1, "implicitly sized array");
984         $$ = new TVector<unsigned int>();
985         $$->push_back(0u);
986     }
987     | LEFT_BRACKET constant_expression RIGHT_BRACKET {
988         $$ = new TVector<unsigned int>();
989         unsigned int size = context->checkIsValidArraySize(@1, $2);
990         // Make the type an array even if size check failed.
991         // This ensures useless error messages regarding a variable's non-arrayness won't follow.
992         $$->push_back(size);
993     }
994     | array_specifier LEFT_BRACKET RIGHT_BRACKET {
995         ES3_1_OR_NEWER("[]", @2, "arrays of arrays");
996         $$ = $1;
997         $$->insert($$->begin(), 0u);
998     }
999     | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
1000         ES3_1_OR_NEWER("[]", @2, "arrays of arrays");
1001         $$ = $1;
1002         unsigned int size = context->checkIsValidArraySize(@2, $3);
1003         // Make the type an array even if size check failed.
1004         // This ensures useless error messages regarding a variable's non-arrayness won't follow.
1005         $$->insert($$->begin(), size);
1006     }
1007     ;
1008 
1009 type_specifier_nonarray
1010     : VOID_TYPE {
1011         $$.initialize(EbtVoid, @1);
1012     }
1013     | FLOAT_TYPE {
1014         $$.initialize(EbtFloat, @1);
1015     }
1016     | INT_TYPE {
1017         $$.initialize(EbtInt, @1);
1018     }
1019     | UINT_TYPE {
1020         $$.initialize(EbtUInt, @1);
1021     }
1022     | BOOL_TYPE {
1023         $$.initialize(EbtBool, @1);
1024     }
1025     | VEC2 {
1026         $$.initialize(EbtFloat, @1);
1027         $$.setAggregate(2);
1028     }
1029     | VEC3 {
1030         $$.initialize(EbtFloat, @1);
1031         $$.setAggregate(3);
1032     }
1033     | VEC4 {
1034         $$.initialize(EbtFloat, @1);
1035         $$.setAggregate(4);
1036     }
1037     | BVEC2 {
1038         $$.initialize(EbtBool, @1);
1039         $$.setAggregate(2);
1040     }
1041     | BVEC3 {
1042         $$.initialize(EbtBool, @1);
1043         $$.setAggregate(3);
1044     }
1045     | BVEC4 {
1046         $$.initialize(EbtBool, @1);
1047         $$.setAggregate(4);
1048     }
1049     | IVEC2 {
1050         $$.initialize(EbtInt, @1);
1051         $$.setAggregate(2);
1052     }
1053     | IVEC3 {
1054         $$.initialize(EbtInt, @1);
1055         $$.setAggregate(3);
1056     }
1057     | IVEC4 {
1058         $$.initialize(EbtInt, @1);
1059         $$.setAggregate(4);
1060     }
1061     | UVEC2 {
1062         $$.initialize(EbtUInt, @1);
1063         $$.setAggregate(2);
1064     }
1065     | UVEC3 {
1066         $$.initialize(EbtUInt, @1);
1067         $$.setAggregate(3);
1068     }
1069     | UVEC4 {
1070         $$.initialize(EbtUInt, @1);
1071         $$.setAggregate(4);
1072     }
1073     | MATRIX2 {
1074         $$.initialize(EbtFloat, @1);
1075         $$.setMatrix(2, 2);
1076     }
1077     | MATRIX3 {
1078         $$.initialize(EbtFloat, @1);
1079         $$.setMatrix(3, 3);
1080     }
1081     | MATRIX4 {
1082         $$.initialize(EbtFloat, @1);
1083         $$.setMatrix(4, 4);
1084     }
1085     | MATRIX2x3 {
1086         $$.initialize(EbtFloat, @1);
1087         $$.setMatrix(2, 3);
1088     }
1089     | MATRIX3x2 {
1090         $$.initialize(EbtFloat, @1);
1091         $$.setMatrix(3, 2);
1092     }
1093     | MATRIX2x4 {
1094         $$.initialize(EbtFloat, @1);
1095         $$.setMatrix(2, 4);
1096     }
1097     | MATRIX4x2 {
1098         $$.initialize(EbtFloat, @1);
1099         $$.setMatrix(4, 2);
1100     }
1101     | MATRIX3x4 {
1102         $$.initialize(EbtFloat, @1);
1103         $$.setMatrix(3, 4);
1104     }
1105     | MATRIX4x3 {
1106         $$.initialize(EbtFloat, @1);
1107         $$.setMatrix(4, 3);
1108     }
1109     | YUVCSCSTANDARDEXT {
1110         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
1111         {
1112             context->error(@1, "unsupported type", "yuvCscStandardEXT");
1113         }
1114         $$.initialize(EbtYuvCscStandardEXT, @1);
1115     }
1116     | SAMPLER2D {
1117         $$.initialize(EbtSampler2D, @1);
1118     }
1119     | SAMPLER3D {
1120         $$.initialize(EbtSampler3D, @1);
1121     }
1122     | SAMPLERCUBE {
1123         $$.initialize(EbtSamplerCube, @1);
1124     }
1125     | SAMPLER2DARRAY {
1126         $$.initialize(EbtSampler2DArray, @1);
1127     }
1128     | SAMPLER2DMS {
1129         $$.initialize(EbtSampler2DMS, @1);
1130     }
1131     | SAMPLER2DMSARRAY {
1132         $$.initialize(EbtSampler2DMSArray, @1);
1133     }
1134     | SAMPLERCUBEARRAYOES {
1135         if (context->getShaderVersion() < 320
1136         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1137         {
1138             context->error(@1, "unsupported type", "__samplerCubeArray");
1139         }
1140         $$.initialize(EbtSamplerCubeArray, @1);
1141     }
1142     | SAMPLERCUBEARRAYEXT {
1143         if (context->getShaderVersion() < 320
1144         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1145         {
1146             context->error(@1, "unsupported type", "__samplerCubeArray");
1147         }
1148         $$.initialize(EbtSamplerCubeArray, @1);
1149     }
1150     | SAMPLERBUFFER {
1151         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1152                                                            TExtension::EXT_texture_buffer } };
1153         if (context->getShaderVersion() < 320
1154         && !context->checkCanUseOneOfExtensions(@1, extensions))
1155         {
1156             context->error(@1, "unsupported type", "__samplerBuffer");
1157         }
1158         $$.initialize(EbtSamplerBuffer, @1);
1159     }
1160     | ISAMPLER2D {
1161         $$.initialize(EbtISampler2D, @1);
1162     }
1163     | ISAMPLER3D {
1164         $$.initialize(EbtISampler3D, @1);
1165     }
1166     | ISAMPLERCUBE {
1167         $$.initialize(EbtISamplerCube, @1);
1168     }
1169     | ISAMPLER2DARRAY {
1170         $$.initialize(EbtISampler2DArray, @1);
1171     }
1172     | ISAMPLER2DMS {
1173         $$.initialize(EbtISampler2DMS, @1);
1174     }
1175     | ISAMPLER2DMSARRAY {
1176         $$.initialize(EbtISampler2DMSArray, @1);
1177     }
1178     | ISAMPLERCUBEARRAYOES {
1179         if (context->getShaderVersion() < 320
1180         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1181         {
1182             context->error(@1, "unsupported type", "__isamplerCubeArray");
1183         }
1184         $$.initialize(EbtISamplerCubeArray, @1);
1185     }
1186     | ISAMPLERCUBEARRAYEXT {
1187         if (context->getShaderVersion() < 320
1188         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1189         {
1190             context->error(@1, "unsupported type", "__isamplerCubeArray");
1191         }
1192         $$.initialize(EbtISamplerCubeArray, @1);
1193     }
1194     | ISAMPLERBUFFER {
1195         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1196                                                            TExtension::EXT_texture_buffer } };
1197         if (context->getShaderVersion() < 320
1198         && !context->checkCanUseOneOfExtensions(@1, extensions))
1199         {
1200             context->error(@1, "unsupported type", "__isamplerBuffer");
1201         }
1202         $$.initialize(EbtISamplerBuffer, @1);
1203     }
1204     | USAMPLER2D {
1205         $$.initialize(EbtUSampler2D, @1);
1206     }
1207     | USAMPLER3D {
1208         $$.initialize(EbtUSampler3D, @1);
1209     }
1210     | USAMPLERCUBE {
1211         $$.initialize(EbtUSamplerCube, @1);
1212     }
1213     | USAMPLER2DARRAY {
1214         $$.initialize(EbtUSampler2DArray, @1);
1215     }
1216     | USAMPLER2DMS {
1217         $$.initialize(EbtUSampler2DMS, @1);
1218     }
1219     | USAMPLER2DMSARRAY {
1220         $$.initialize(EbtUSampler2DMSArray, @1);
1221     }
1222     | USAMPLERCUBEARRAYOES {
1223         if (context->getShaderVersion() < 320
1224         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1225         {
1226             context->error(@1, "unsupported type", "__usamplerCubeArray");
1227         }
1228         $$.initialize(EbtUSamplerCubeArray, @1);
1229     }
1230     | USAMPLERCUBEARRAYEXT {
1231         if (context->getShaderVersion() < 320
1232         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1233         {
1234             context->error(@1, "unsupported type", "__usamplerCubeArray");
1235         }
1236         $$.initialize(EbtUSamplerCubeArray, @1);
1237     }
1238     | USAMPLERBUFFER {
1239         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1240                                                            TExtension::EXT_texture_buffer } };
1241         if (context->getShaderVersion() < 320
1242         && !context->checkCanUseOneOfExtensions(@1, extensions))
1243         {
1244             context->error(@1, "unsupported type", "__usamplerBuffer");
1245         }
1246         $$.initialize(EbtUSamplerBuffer, @1);
1247     }
1248     | SAMPLER2DSHADOW {
1249         $$.initialize(EbtSampler2DShadow, @1);
1250     }
1251     | SAMPLERCUBESHADOW {
1252         $$.initialize(EbtSamplerCubeShadow, @1);
1253     }
1254     | SAMPLER2DARRAYSHADOW {
1255         $$.initialize(EbtSampler2DArrayShadow, @1);
1256     }
1257     | SAMPLERCUBEARRAYSHADOWOES {
1258         if (context->getShaderVersion() < 320
1259         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1260         {
1261             context->error(@1, "unsupported type", "__samplerCubeArrayShadow");
1262         }
1263         $$.initialize(EbtSamplerCubeArrayShadow, @1);
1264     }
1265     | SAMPLERCUBEARRAYSHADOWEXT {
1266         if (context->getShaderVersion() < 320
1267         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1268         {
1269             context->error(@1, "unsupported type", "__samplerCubeArrayShadow");
1270         }
1271         $$.initialize(EbtSamplerCubeArrayShadow, @1);
1272     }
1273     | SAMPLERVIDEOWEBGL {
1274         if (!context->checkCanUseExtension(@1, TExtension::WEBGL_video_texture))
1275         {
1276             context->error(@1, "unsupported type", "samplerVideoWEBGL");
1277         }
1278         $$.initialize(EbtSamplerVideoWEBGL, @1);
1279     }
1280     | SAMPLER_EXTERNAL_OES {
1281         constexpr std::array<TExtension, 3u> extensions{ { TExtension::NV_EGL_stream_consumer_external,
1282                                                            TExtension::OES_EGL_image_external_essl3,
1283                                                            TExtension::OES_EGL_image_external } };
1284         if (!context->checkCanUseOneOfExtensions(@1, extensions))
1285         {
1286             context->error(@1, "unsupported type", "samplerExternalOES");
1287         }
1288         $$.initialize(EbtSamplerExternalOES, @1);
1289     }
1290     | SAMPLEREXTERNAL2DY2YEXT {
1291         if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target))
1292         {
1293             context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT");
1294         }
1295         $$.initialize(EbtSamplerExternal2DY2YEXT, @1);
1296     }
1297     | SAMPLER2DRECT {
1298         if (!context->checkCanUseExtension(@1, TExtension::ARB_texture_rectangle))
1299         {
1300             context->error(@1, "unsupported type", "sampler2DRect");
1301         }
1302         $$.initialize(EbtSampler2DRect, @1);
1303     }
1304     | IMAGE2D {
1305         $$.initialize(EbtImage2D, @1);
1306     }
1307     | IIMAGE2D {
1308         $$.initialize(EbtIImage2D, @1);
1309     }
1310     | UIMAGE2D {
1311         $$.initialize(EbtUImage2D, @1);
1312     }
1313     | IMAGE3D {
1314         $$.initialize(EbtImage3D, @1);
1315     }
1316     | IIMAGE3D {
1317         $$.initialize(EbtIImage3D, @1);
1318     }
1319     | UIMAGE3D {
1320         $$.initialize(EbtUImage3D, @1);
1321     }
1322     | IMAGE2DARRAY {
1323         $$.initialize(EbtImage2DArray, @1);
1324     }
1325     | IIMAGE2DARRAY {
1326         $$.initialize(EbtIImage2DArray, @1);
1327     }
1328     | UIMAGE2DARRAY {
1329         $$.initialize(EbtUImage2DArray, @1);
1330     }
1331     | IMAGECUBE {
1332         $$.initialize(EbtImageCube, @1);
1333     }
1334     | IIMAGECUBE {
1335         $$.initialize(EbtIImageCube, @1);
1336     }
1337     | UIMAGECUBE {
1338         $$.initialize(EbtUImageCube, @1);
1339     }
1340     | IMAGECUBEARRAYOES {
1341         if (context->getShaderVersion() < 320
1342         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1343         {
1344             context->error(@1, "unsupported type", "__imageCubeArray");
1345         }
1346         $$.initialize(EbtImageCubeArray, @1);
1347     }
1348     | IMAGECUBEARRAYEXT {
1349         if (context->getShaderVersion() < 320
1350         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1351         {
1352             context->error(@1, "unsupported type", "__imageCubeArray");
1353         }
1354         $$.initialize(EbtImageCubeArray, @1);
1355     }
1356     | IIMAGECUBEARRAYOES {
1357         if (context->getShaderVersion() < 320
1358         && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1359         {
1360             context->error(@1, "unsupported type", "__iimageCubeArray");
1361         }
1362         $$.initialize(EbtIImageCubeArray, @1);
1363     }
1364     | IIMAGECUBEARRAYEXT {
1365         if (context->getShaderVersion() < 320
1366         && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1367         {
1368             context->error(@1, "unsupported type", "__iimageCubeArray");
1369         }
1370         $$.initialize(EbtIImageCubeArray, @1);
1371     }
1372     | UIMAGECUBEARRAYOES {
1373        if (context->getShaderVersion() < 320
1374        && !context->checkCanUseExtension(@1, TExtension::OES_texture_cube_map_array))
1375         {
1376             context->error(@1, "unsupported type", "__uimageCubeArray");
1377         }
1378         $$.initialize(EbtUImageCubeArray, @1);
1379     }
1380     | UIMAGECUBEARRAYEXT {
1381        if (context->getShaderVersion() < 320
1382        && !context->checkCanUseExtension(@1, TExtension::EXT_texture_cube_map_array))
1383         {
1384             context->error(@1, "unsupported type", "__uimageCubeArray");
1385         }
1386         $$.initialize(EbtUImageCubeArray, @1);
1387     }
1388     | IMAGEBUFFER {
1389         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1390                                                            TExtension::EXT_texture_buffer } };
1391         if (context->getShaderVersion() < 320
1392         && !context->checkCanUseOneOfExtensions(@1, extensions))
1393         {
1394             context->error(@1, "unsupported type", "__imageBuffer");
1395         }
1396         $$.initialize(EbtImageBuffer, @1);
1397     }
1398     | IIMAGEBUFFER {
1399         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1400                                                            TExtension::EXT_texture_buffer } };
1401         if (context->getShaderVersion() < 320
1402         && !context->checkCanUseOneOfExtensions(@1, extensions))
1403         {
1404             context->error(@1, "unsupported type", "__iimageBuffer");
1405         }
1406         $$.initialize(EbtIImageBuffer, @1);
1407     }
1408     | UIMAGEBUFFER {
1409         constexpr std::array<TExtension, 2u> extensions{ { TExtension::OES_texture_buffer,
1410                                                            TExtension::EXT_texture_buffer } };
1411         if (context->getShaderVersion() < 320
1412         && !context->checkCanUseOneOfExtensions(@1, extensions))
1413         {
1414             context->error(@1, "unsupported type", "__uimageBuffer");
1415         }
1416         $$.initialize(EbtUImageBuffer, @1);
1417     }
1418     | ATOMICUINT {
1419         $$.initialize(EbtAtomicCounter, @1);
1420     }
1421     | struct_specifier {
1422         $$ = $1;
1423     }
1424     | TYPE_NAME {
1425         // This is for user defined type names. The lexical phase looked up the type.
1426         const TStructure *structure = static_cast<const TStructure*>($1.symbol);
1427         $$.initializeStruct(structure, false, @1);
1428     }
1429     ;
1430 
1431 struct_specifier
1432     : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, ImmutableString($2.string)); } struct_declaration_list RIGHT_BRACE {
1433         $$ = context->addStructure(@1, @2, ImmutableString($2.string), $5);
1434     }
1435     | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, kEmptyImmutableString); } struct_declaration_list RIGHT_BRACE {
1436         $$ = context->addStructure(@1, @$, kEmptyImmutableString, $4);
1437     }
1438     ;
1439 
1440 struct_declaration_list
1441     : struct_declaration {
1442         $$ = context->addStructFieldList($1, @1);
1443     }
1444     | struct_declaration_list struct_declaration {
1445         $$ = context->combineStructFieldLists($1, $2, @2);
1446     }
1447     ;
1448 
1449 struct_declaration
1450     : type_specifier struct_declarator_list SEMICOLON {
1451         $$ = context->addStructDeclaratorList($1, $2);
1452     }
1453     | type_qualifier type_specifier struct_declarator_list SEMICOLON {
1454         // ES3 Only, but errors should be handled elsewhere
1455         $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3);
1456     }
1457     ;
1458 
1459 struct_declarator_list
1460     : struct_declarator {
1461         $$ = new TDeclaratorList();
1462         $$->push_back($1);
1463     }
1464     | struct_declarator_list COMMA struct_declarator {
1465         $$->push_back($3);
1466     }
1467     ;
1468 
1469 struct_declarator
1470     : identifier {
1471         $$ = context->parseStructDeclarator(ImmutableString($1.string), @1);
1472     }
1473     | identifier array_specifier {
1474         $$ = context->parseStructArrayDeclarator(ImmutableString($1.string), @1, $2);
1475     }
1476     ;
1477 
1478 initializer
1479     : assignment_expression { $$ = $1; }
1480     ;
1481 
1482 declaration_statement
1483     : declaration { $$ = $1; }
1484     ;
1485 
1486 statement
1487     : compound_statement_with_scope { $$ = $1; }
1488     | simple_statement              { $$ = $1; }
1489     ;
1490 
1491 // Grammar Note:  Labeled statements for SWITCH only; 'goto' is not supported.
1492 
1493 simple_statement
1494     : declaration_statement { $$ = $1; }
1495     | expression_statement  { $$ = $1; }
1496     | selection_statement   { $$ = $1; }
1497     | switch_statement      { $$ = $1; }
1498     | case_label            { $$ = $1; }
1499     | iteration_statement   { $$ = $1; }
1500     | jump_statement        { $$ = $1; }
1501     ;
1502 
1503 compound_statement_with_scope
1504     : LEFT_BRACE RIGHT_BRACE {
1505         $$ = new TIntermBlock();
1506         $$->setLine(@$);
1507     }
1508     | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
1509         $3->setLine(@$);
1510         $$ = $3;
1511     }
1512     ;
1513 
1514 statement_no_new_scope
1515     : compound_statement_no_new_scope { $$ = $1; }
1516     | simple_statement                { $$ = $1; }
1517     ;
1518 
1519 statement_with_scope
1520     : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; }
1521     | { context->symbolTable.push(); } simple_statement                { context->symbolTable.pop(); $$ = $2; }
1522     ;
1523 
1524 compound_statement_no_new_scope
1525     // Statement that doesn't create a new scope for iteration_statement, function definition (scope is created for parameters)
1526     : LEFT_BRACE RIGHT_BRACE {
1527         $$ = new TIntermBlock();
1528         $$->setLine(@$);
1529     }
1530     | LEFT_BRACE statement_list RIGHT_BRACE {
1531         $2->setLine(@$);
1532         $$ = $2;
1533     }
1534     ;
1535 
1536 statement_list
1537     : statement {
1538         $$ = new TIntermBlock();
1539         context->appendStatement($$, $1);
1540     }
1541     | statement_list statement {
1542         $$ = $1;
1543         context->appendStatement($$, $2);
1544     }
1545     ;
1546 
1547 expression_statement
1548     : SEMICOLON  { $$ = context->addEmptyStatement(@$); }
1549     | expression SEMICOLON  { $$ = $1; }
1550     ;
1551 
1552 selection_statement
1553     : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
1554         $$ = context->addIfElse($3, $5, @1);
1555     }
1556     ;
1557 
1558 selection_rest_statement
1559     : statement_with_scope ELSE statement_with_scope {
1560         $$.node1 = $1;
1561         $$.node2 = $3;
1562     }
1563     | statement_with_scope {
1564         $$.node1 = $1;
1565         $$.node2 = nullptr;
1566     }
1567     ;
1568 
1569 // Note that we've diverged from the spec grammar here a bit for the sake of simplicity.
1570 // We're reusing compound_statement_with_scope instead of having separate rules for switch.
1571 switch_statement
1572     : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement_with_scope {
1573         $$ = context->addSwitch($3, $6, @1);
1574         context->decrSwitchNestingLevel();
1575     }
1576     ;
1577 
1578 case_label
1579     : CASE constant_expression COLON {
1580         $$ = context->addCase($2, @1);
1581     }
1582     | DEFAULT COLON {
1583         $$ = context->addDefault(@1);
1584     }
1585     ;
1586 
1587 condition
1588     : expression {
1589         $$ = $1;
1590         context->checkIsScalarBool($1->getLine(), $1);
1591     }
1592     | fully_specified_type identifier EQUAL initializer {
1593         $$ = context->addConditionInitializer($1, ImmutableString($2.string), $4, @2);
1594     }
1595     ;
1596 
1597 iteration_statement
1598     : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } condition RIGHT_PAREN statement_no_new_scope {
1599         context->symbolTable.pop();
1600         $$ = context->addLoop(ELoopWhile, 0, $4, 0, $6, @1);
1601         context->decrLoopNestingLevel();
1602     }
1603     | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
1604         $$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
1605         context->decrLoopNestingLevel();
1606     }
1607     | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
1608         context->symbolTable.pop();
1609         $$ = context->addLoop(ELoopFor, $4, $5.node1, reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
1610         context->decrLoopNestingLevel();
1611     }
1612     ;
1613 
1614 for_init_statement
1615     : expression_statement {
1616         $$ = $1;
1617     }
1618     | declaration_statement {
1619         $$ = $1;
1620     }
1621     ;
1622 
1623 conditionopt
1624     : condition {
1625         $$ = $1;
1626     }
1627     | /* May be null */ {
1628         $$ = nullptr;
1629     }
1630     ;
1631 
1632 for_rest_statement
1633     : conditionopt SEMICOLON {
1634         $$.node1 = $1;
1635         $$.node2 = 0;
1636     }
1637     | conditionopt SEMICOLON expression  {
1638         $$.node1 = $1;
1639         $$.node2 = $3;
1640     }
1641     ;
1642 
1643 jump_statement
1644     : CONTINUE SEMICOLON {
1645         $$ = context->addBranch(EOpContinue, @1);
1646     }
1647     | BREAK SEMICOLON {
1648         $$ = context->addBranch(EOpBreak, @1);
1649     }
1650     | RETURN SEMICOLON {
1651         $$ = context->addBranch(EOpReturn, @1);
1652     }
1653     | RETURN expression SEMICOLON {
1654         $$ = context->addBranch(EOpReturn, $2, @1);
1655     }
1656     | DISCARD SEMICOLON {
1657         $$ = context->addBranch(EOpKill, @1);
1658     }
1659     ;
1660 
1661 // Grammar Note:  No 'goto'.  Gotos are not supported.
1662 
1663 translation_unit
1664     : external_declaration {
1665         $$ = new TIntermBlock();
1666         $$->setLine(@$);
1667         $$->appendStatement($1);
1668         context->setTreeRoot($$);
1669     }
1670     | translation_unit external_declaration {
1671         $$->appendStatement($2);
1672     }
1673     ;
1674 
1675 external_declaration
1676     : function_definition {
1677         $$ = $1;
1678     }
1679     | declaration {
1680         $$ = $1;
1681     }
1682     ;
1683 
1684 function_definition
1685     : function_prototype {
1686         context->parseFunctionDefinitionHeader(@1, $1.function, &($1.intermFunctionPrototype));
1687     }
1688     compound_statement_no_new_scope {
1689         $$ = context->addFunctionDefinition($1.intermFunctionPrototype, $3, @1);
1690     }
1691     ;
1692 
1693 %%
1694 
1695 int glslang_parse(TParseContext* context) {
1696     return yyparse(context, context->getScanner());
1697 }
1698