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