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