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