1 /* 2 // 3 // Copyright (c) 2002-2014 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 generate_parser.sh, 13 WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). 14 */ 15 16 %{ 17 // 18 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 19 // Use of this source code is governed by a BSD-style license that can be 20 // found in the LICENSE file. 21 // 22 23 // This file is auto-generated by generate_parser.sh. DO NOT EDIT! 24 25 // clang-format off 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 41 #include "angle_gl.h" 42 #include "compiler/translator/Cache.h" 43 #include "compiler/translator/SymbolTable.h" 44 #include "compiler/translator/ParseContext.h" 45 #include "GLSLANG/ShaderLang.h" 46 47 #define YYENABLE_NLS 0 48 49 using namespace sh; 50 51 %} 52 %expect 1 /* One shift reduce conflict because of if | else */ 53 %parse-param {TParseContext* context} 54 %param {void *scanner} 55 %define api.pure full 56 %locations 57 58 %code requires { 59 #define YYLTYPE TSourceLoc 60 #define YYLTYPE_IS_DECLARED 1 61 } 62 63 %union { 64 struct { 65 union { 66 TString *string; 67 float f; 68 int i; 69 unsigned int u; 70 bool b; 71 }; 72 TSymbol* symbol; 73 } lex; 74 struct { 75 TOperator op; 76 union { 77 TIntermNode *intermNode; 78 TIntermNodePair nodePair; 79 TIntermFunctionCallOrMethod callOrMethodPair; 80 TIntermTyped *intermTypedNode; 81 TIntermAggregate *intermAggregate; 82 TIntermBlock *intermBlock; 83 TIntermDeclaration *intermDeclaration; 84 TIntermFunctionPrototype *intermFunctionPrototype; 85 TIntermSwitch *intermSwitch; 86 TIntermCase *intermCase; 87 }; 88 union { 89 TVector<unsigned int> *arraySizes; 90 TTypeSpecifierNonArray typeSpecifierNonArray; 91 TPublicType type; 92 TPrecision precision; 93 TLayoutQualifier layoutQualifier; 94 TQualifier qualifier; 95 TFunction *function; 96 TParameter param; 97 TField *field; 98 TFieldList *fieldList; 99 TQualifierWrapperBase *qualifierWrapper; 100 TTypeQualifierBuilder *typeQualifierBuilder; 101 }; 102 } interm; 103 } 104 105 %{ 106 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner); 107 extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, const char* reason); 108 109 #define YYLLOC_DEFAULT(Current, Rhs, N) \ 110 do { \ 111 if (N) { \ 112 (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \ 113 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ 114 (Current).last_file = YYRHSLOC(Rhs, N).last_file; \ 115 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ 116 } \ 117 else { \ 118 (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \ 119 (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ 120 (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \ 121 (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \ 122 } \ 123 } while (0) 124 125 #define VERTEX_ONLY(S, L) { \ 126 if (context->getShaderType() != GL_VERTEX_SHADER) { \ 127 context->error(L, " supported in vertex shaders only", S); \ 128 } \ 129 } 130 131 #define COMPUTE_ONLY(S, L) { \ 132 if (context->getShaderType() != GL_COMPUTE_SHADER) { \ 133 context->error(L, " supported in compute shaders only", S); \ 134 } \ 135 } 136 137 #define ES2_ONLY(S, L) { \ 138 if (context->getShaderVersion() != 100) { \ 139 context->error(L, " supported in GLSL ES 1.00 only", S); \ 140 } \ 141 } 142 143 #define ES3_OR_NEWER(TOKEN, LINE, REASON) { \ 144 if (context->getShaderVersion() < 300) { \ 145 context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \ 146 } \ 147 } 148 149 #define ES3_OR_NEWER_OR_MULTIVIEW(TOKEN, LINE, REASON) { \ 150 if (context->getShaderVersion() < 300 && !context->isExtensionEnabled(TExtension::OVR_multiview)) { \ 151 context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \ 152 } \ 153 } 154 155 #define ES3_1_ONLY(TOKEN, LINE, REASON) { \ 156 if (context->getShaderVersion() != 310) { \ 157 context->error(LINE, REASON " supported in GLSL ES 3.10 only", TOKEN); \ 158 } \ 159 } 160 %} 161 162 %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION 163 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE 164 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT 165 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4 166 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM BUFFER VARYING 167 %token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3 168 %token <lex> CENTROID FLAT SMOOTH 169 %token <lex> READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED 170 %token <lex> STRUCT VOID_TYPE WHILE 171 %token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY 172 %token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY 173 %token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY 174 %token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS 175 %token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW 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 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.field> struct_declarator 236 %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list 237 %type <interm.function> function_header function_declarator function_identifier 238 %type <interm.function> function_header_with_parameters function_call_header 239 %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype 240 %type <interm> function_call_or_method 241 242 %type <lex> enter_struct 243 244 %start translation_unit 245 %% 246 247 identifier 248 : IDENTIFIER 249 | TYPE_NAME 250 251 variable_identifier 252 : IDENTIFIER { 253 // The symbol table search was done in the lexical phase 254 $$ = context->parseVariableIdentifier(@1, $1.string, $1.symbol); 255 256 // don't delete $1.string, it's used by error recovery, and the pool 257 // pop will reclaim the memory 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", $1.string->c_str()); 289 } 290 TConstantUnion *unionArray = new TConstantUnion[1]; 291 unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT($1.string->c_str())); 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, *$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.function, $1.callOrMethodPair.arguments, $1.callOrMethodPair.thisNode, @1); 330 } 331 ; 332 333 function_call_or_method 334 : function_call_generic { 335 $$ = $1; 336 $$.callOrMethodPair.thisNode = nullptr; 337 } 338 | postfix_expression DOT function_call_generic { 339 ES3_OR_NEWER("", @3, "methods"); 340 $$ = $3; 341 $$.callOrMethodPair.thisNode = $1; 342 } 343 ; 344 345 function_call_generic 346 : function_call_header_with_parameters RIGHT_PAREN { 347 $$ = $1; 348 } 349 | function_call_header_no_parameters RIGHT_PAREN { 350 $$ = $1; 351 } 352 ; 353 354 function_call_header_no_parameters 355 : function_call_header VOID_TYPE { 356 $$.function = $1; 357 $$.callOrMethodPair.arguments = context->createEmptyArgumentsList(); 358 } 359 | function_call_header { 360 $$.function = $1; 361 $$.callOrMethodPair.arguments = context->createEmptyArgumentsList(); 362 } 363 ; 364 365 function_call_header_with_parameters 366 : function_call_header assignment_expression { 367 $$.callOrMethodPair.arguments = context->createEmptyArgumentsList(); 368 $$.function = $1; 369 $$.callOrMethodPair.arguments->push_back($2); 370 } 371 | function_call_header_with_parameters COMMA assignment_expression { 372 $$.function = $1.function; 373 $$.callOrMethodPair.arguments->push_back($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($1.string, @1); 391 } 392 | FIELD_SELECTION { 393 $$ = context->addNonConstructorFunc($1.string, @1); 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, *$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($2.string->c_str(), @1, "interface blocks"); 613 $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, NULL, @$, NULL, @$); 614 } 615 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { 616 ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); 617 $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $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($2.string->c_str(), @1, "interface blocks"); 621 $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $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 628 { 629 $$ = context->parseInvariantDeclaration(*$1, @2, $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.turnToConst()); 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.turnToConst()); 671 } 672 } 673 ; 674 675 function_header 676 : fully_specified_type IDENTIFIER LEFT_PAREN { 677 $$ = context->parseFunctionHeader($1, $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, $2.string, @2); 688 } 689 | type_specifier identifier array_specifier { 690 $$ = context->parseParameterArrayDeclarator($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, *$3.string, $$.intermDeclaration); 727 } 728 | init_declarator_list COMMA identifier array_specifier { 729 $$ = $1; 730 context->parseArrayDeclarator($$.type, @3, *$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, *$3.string, @4, *($4), @5, $6, $$.intermDeclaration); 736 } 737 | init_declarator_list COMMA identifier EQUAL initializer { 738 $$ = $1; 739 context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration); 740 } 741 ; 742 743 single_declaration 744 : fully_specified_type { 745 $$.type = $1; 746 $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, ""); 747 } 748 | fully_specified_type identifier { 749 $$.type = $1; 750 $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string); 751 } 752 | fully_specified_type identifier array_specifier { 753 $$.type = $1; 754 $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$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, *$2.string, @3, *($3), @4, $5); 760 } 761 | fully_specified_type identifier EQUAL initializer { 762 $$.type = $1; 763 $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$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 ; 785 786 type_qualifier 787 : single_type_qualifier { 788 $$ = context->createTypeQualifierBuilder(@1); 789 $$->appendQualifier($1); 790 } 791 | type_qualifier single_type_qualifier { 792 $$ = $1; 793 $$->appendQualifier($2); 794 } 795 ; 796 797 invariant_qualifier 798 : INVARIANT { 799 // empty 800 } 801 ; 802 803 single_type_qualifier 804 : storage_qualifier { 805 context->checkLocalVariableConstStorageQualifier(*$1); 806 $$ = $1; 807 } 808 | layout_qualifier { 809 context->checkIsAtGlobalLevel(@1, "layout"); 810 $$ = new TLayoutQualifierWrapper($1, @1); 811 } 812 | precision_qualifier { 813 $$ = new TPrecisionQualifierWrapper($1, @1); 814 } 815 | interpolation_qualifier { 816 $$ = new TInterpolationQualifierWrapper($1, @1); 817 } 818 | invariant_qualifier { 819 context->checkIsAtGlobalLevel(@1, "invariant"); 820 $$ = new TInvariantQualifierWrapper(@1); 821 } 822 ; 823 824 825 storage_qualifier 826 : 827 ATTRIBUTE { 828 VERTEX_ONLY("attribute", @1); 829 ES2_ONLY("attribute", @1); 830 $$ = context->parseGlobalStorageQualifier(EvqAttribute, @1); 831 } 832 | VARYING { 833 ES2_ONLY("varying", @1); 834 $$ = context->parseVaryingQualifier(@1); 835 } 836 | CONST_QUAL { 837 $$ = new TStorageQualifierWrapper(EvqConst, @1); 838 } 839 | IN_QUAL { 840 $$ = context->parseInQualifier(@1); 841 } 842 | OUT_QUAL { 843 $$ = context->parseOutQualifier(@1); 844 } 845 | INOUT_QUAL { 846 $$ = context->parseInOutQualifier(@1); 847 } 848 | CENTROID { 849 ES3_OR_NEWER("centroid", @1, "storage qualifier"); 850 $$ = new TStorageQualifierWrapper(EvqCentroid, @1); 851 } 852 | UNIFORM { 853 $$ = context->parseGlobalStorageQualifier(EvqUniform, @1); 854 } 855 | BUFFER { 856 ES3_1_ONLY("buffer", @1, "storage qualifier"); 857 $$ = context->parseGlobalStorageQualifier(EvqBuffer, @1); 858 } 859 | READONLY { 860 $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1); 861 } 862 | WRITEONLY { 863 $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1); 864 } 865 | COHERENT { 866 $$ = new TMemoryQualifierWrapper(EvqCoherent, @1); 867 } 868 | RESTRICT { 869 $$ = new TMemoryQualifierWrapper(EvqRestrict, @1); 870 } 871 | VOLATILE { 872 $$ = new TMemoryQualifierWrapper(EvqVolatile, @1); 873 } 874 | SHARED { 875 COMPUTE_ONLY("shared", @1); 876 $$ = context->parseGlobalStorageQualifier(EvqShared, @1); 877 } 878 ; 879 880 type_specifier 881 : type_specifier_no_prec { 882 $$ = $1; 883 $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType()); 884 } 885 ; 886 887 precision_qualifier 888 : HIGH_PRECISION { 889 $$ = EbpHigh; 890 } 891 | MEDIUM_PRECISION { 892 $$ = EbpMedium; 893 } 894 | LOW_PRECISION { 895 $$ = EbpLow; 896 } 897 ; 898 899 layout_qualifier 900 : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { 901 ES3_OR_NEWER_OR_MULTIVIEW("layout", @1, "qualifier"); 902 $$ = $3; 903 } 904 ; 905 906 layout_qualifier_id_list 907 : layout_qualifier_id { 908 $$ = $1; 909 } 910 | layout_qualifier_id_list COMMA layout_qualifier_id { 911 $$ = context->joinLayoutQualifiers($1, $3, @3); 912 } 913 ; 914 915 layout_qualifier_id 916 : IDENTIFIER { 917 $$ = context->parseLayoutQualifier(*$1.string, @1); 918 } 919 | IDENTIFIER EQUAL INTCONSTANT { 920 $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3); 921 } 922 | IDENTIFIER EQUAL UINTCONSTANT { 923 $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3); 924 } 925 | SHARED { 926 $$ = context->parseLayoutQualifier("shared", @1); 927 } 928 ; 929 930 type_specifier_no_prec 931 : type_specifier_nonarray { 932 $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); 933 } 934 | type_specifier_nonarray array_specifier { 935 $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); 936 $$.setArraySizes($2); 937 } 938 ; 939 940 array_specifier 941 : LEFT_BRACKET RIGHT_BRACKET { 942 ES3_OR_NEWER("[]", @1, "implicitly sized array"); 943 $$ = new TVector<unsigned int>(); 944 $$->push_back(0u); 945 } 946 | LEFT_BRACKET constant_expression RIGHT_BRACKET { 947 $$ = new TVector<unsigned int>(); 948 unsigned int size = context->checkIsValidArraySize(@1, $2); 949 // Make the type an array even if size check failed. 950 // This ensures useless error messages regarding a variable's non-arrayness won't follow. 951 $$->push_back(size); 952 } 953 | array_specifier LEFT_BRACKET RIGHT_BRACKET { 954 ES3_1_ONLY("[]", @2, "arrays of arrays"); 955 $$ = $1; 956 $$->insert($$->begin(), 0u); 957 } 958 | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET { 959 ES3_1_ONLY("[]", @2, "arrays of arrays"); 960 $$ = $1; 961 unsigned int size = context->checkIsValidArraySize(@2, $3); 962 // Make the type an array even if size check failed. 963 // This ensures useless error messages regarding a variable's non-arrayness won't follow. 964 $$->insert($$->begin(), size); 965 } 966 ; 967 968 type_specifier_nonarray 969 : VOID_TYPE { 970 $$.initialize(EbtVoid, @1); 971 } 972 | FLOAT_TYPE { 973 $$.initialize(EbtFloat, @1); 974 } 975 | INT_TYPE { 976 $$.initialize(EbtInt, @1); 977 } 978 | UINT_TYPE { 979 $$.initialize(EbtUInt, @1); 980 } 981 | BOOL_TYPE { 982 $$.initialize(EbtBool, @1); 983 } 984 | VEC2 { 985 $$.initialize(EbtFloat, @1); 986 $$.setAggregate(2); 987 } 988 | VEC3 { 989 $$.initialize(EbtFloat, @1); 990 $$.setAggregate(3); 991 } 992 | VEC4 { 993 $$.initialize(EbtFloat, @1); 994 $$.setAggregate(4); 995 } 996 | BVEC2 { 997 $$.initialize(EbtBool, @1); 998 $$.setAggregate(2); 999 } 1000 | BVEC3 { 1001 $$.initialize(EbtBool, @1); 1002 $$.setAggregate(3); 1003 } 1004 | BVEC4 { 1005 $$.initialize(EbtBool, @1); 1006 $$.setAggregate(4); 1007 } 1008 | IVEC2 { 1009 $$.initialize(EbtInt, @1); 1010 $$.setAggregate(2); 1011 } 1012 | IVEC3 { 1013 $$.initialize(EbtInt, @1); 1014 $$.setAggregate(3); 1015 } 1016 | IVEC4 { 1017 $$.initialize(EbtInt, @1); 1018 $$.setAggregate(4); 1019 } 1020 | UVEC2 { 1021 $$.initialize(EbtUInt, @1); 1022 $$.setAggregate(2); 1023 } 1024 | UVEC3 { 1025 $$.initialize(EbtUInt, @1); 1026 $$.setAggregate(3); 1027 } 1028 | UVEC4 { 1029 $$.initialize(EbtUInt, @1); 1030 $$.setAggregate(4); 1031 } 1032 | MATRIX2 { 1033 $$.initialize(EbtFloat, @1); 1034 $$.setMatrix(2, 2); 1035 } 1036 | MATRIX3 { 1037 $$.initialize(EbtFloat, @1); 1038 $$.setMatrix(3, 3); 1039 } 1040 | MATRIX4 { 1041 $$.initialize(EbtFloat, @1); 1042 $$.setMatrix(4, 4); 1043 } 1044 | MATRIX2x3 { 1045 $$.initialize(EbtFloat, @1); 1046 $$.setMatrix(2, 3); 1047 } 1048 | MATRIX3x2 { 1049 $$.initialize(EbtFloat, @1); 1050 $$.setMatrix(3, 2); 1051 } 1052 | MATRIX2x4 { 1053 $$.initialize(EbtFloat, @1); 1054 $$.setMatrix(2, 4); 1055 } 1056 | MATRIX4x2 { 1057 $$.initialize(EbtFloat, @1); 1058 $$.setMatrix(4, 2); 1059 } 1060 | MATRIX3x4 { 1061 $$.initialize(EbtFloat, @1); 1062 $$.setMatrix(3, 4); 1063 } 1064 | MATRIX4x3 { 1065 $$.initialize(EbtFloat, @1); 1066 $$.setMatrix(4, 3); 1067 } 1068 | YUVCSCSTANDARDEXT { 1069 if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target)) 1070 { 1071 context->error(@1, "unsupported type", "yuvCscStandardEXT"); 1072 } 1073 $$.initialize(EbtYuvCscStandardEXT, @1); 1074 } 1075 | SAMPLER2D { 1076 $$.initialize(EbtSampler2D, @1); 1077 } 1078 | SAMPLER3D { 1079 $$.initialize(EbtSampler3D, @1); 1080 } 1081 | SAMPLERCUBE { 1082 $$.initialize(EbtSamplerCube, @1); 1083 } 1084 | SAMPLER2DARRAY { 1085 $$.initialize(EbtSampler2DArray, @1); 1086 } 1087 | SAMPLER2DMS { 1088 $$.initialize(EbtSampler2DMS, @1); 1089 } 1090 | ISAMPLER2D { 1091 $$.initialize(EbtISampler2D, @1); 1092 } 1093 | ISAMPLER3D { 1094 $$.initialize(EbtISampler3D, @1); 1095 } 1096 | ISAMPLERCUBE { 1097 $$.initialize(EbtISamplerCube, @1); 1098 } 1099 | ISAMPLER2DARRAY { 1100 $$.initialize(EbtISampler2DArray, @1); 1101 } 1102 | ISAMPLER2DMS { 1103 $$.initialize(EbtISampler2DMS, @1); 1104 } 1105 | USAMPLER2D { 1106 $$.initialize(EbtUSampler2D, @1); 1107 } 1108 | USAMPLER3D { 1109 $$.initialize(EbtUSampler3D, @1); 1110 } 1111 | USAMPLERCUBE { 1112 $$.initialize(EbtUSamplerCube, @1); 1113 } 1114 | USAMPLER2DARRAY { 1115 $$.initialize(EbtUSampler2DArray, @1); 1116 } 1117 | USAMPLER2DMS { 1118 $$.initialize(EbtUSampler2DMS, @1); 1119 } 1120 | SAMPLER2DSHADOW { 1121 $$.initialize(EbtSampler2DShadow, @1); 1122 } 1123 | SAMPLERCUBESHADOW { 1124 $$.initialize(EbtSamplerCubeShadow, @1); 1125 } 1126 | SAMPLER2DARRAYSHADOW { 1127 $$.initialize(EbtSampler2DArrayShadow, @1); 1128 } 1129 | SAMPLER_EXTERNAL_OES { 1130 constexpr std::array<TExtension, 3u> extensions{ { TExtension::NV_EGL_stream_consumer_external, 1131 TExtension::OES_EGL_image_external_essl3, 1132 TExtension::OES_EGL_image_external } }; 1133 if (!context->checkCanUseOneOfExtensions(@1, extensions)) 1134 { 1135 context->error(@1, "unsupported type", "samplerExternalOES"); 1136 } 1137 $$.initialize(EbtSamplerExternalOES, @1); 1138 } 1139 | SAMPLEREXTERNAL2DY2YEXT { 1140 if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target)) 1141 { 1142 context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT"); 1143 } 1144 $$.initialize(EbtSamplerExternal2DY2YEXT, @1); 1145 } 1146 | SAMPLER2DRECT { 1147 if (!context->checkCanUseExtension(@1, TExtension::ARB_texture_rectangle)) 1148 { 1149 context->error(@1, "unsupported type", "sampler2DRect"); 1150 } 1151 $$.initialize(EbtSampler2DRect, @1); 1152 } 1153 | struct_specifier { 1154 $$ = $1; 1155 } 1156 | IMAGE2D { 1157 $$.initialize(EbtImage2D, @1); 1158 } 1159 | IIMAGE2D { 1160 $$.initialize(EbtIImage2D, @1); 1161 } 1162 | UIMAGE2D { 1163 $$.initialize(EbtUImage2D, @1); 1164 } 1165 | IMAGE3D { 1166 $$.initialize(EbtImage3D, @1); 1167 } 1168 | IIMAGE3D { 1169 $$.initialize(EbtIImage3D, @1); 1170 } 1171 | UIMAGE3D { 1172 $$.initialize(EbtUImage3D, @1); 1173 } 1174 | IMAGE2DARRAY { 1175 $$.initialize(EbtImage2DArray, @1); 1176 } 1177 | IIMAGE2DARRAY { 1178 $$.initialize(EbtIImage2DArray, @1); 1179 } 1180 | UIMAGE2DARRAY { 1181 $$.initialize(EbtUImage2DArray, @1); 1182 } 1183 | IMAGECUBE { 1184 $$.initialize(EbtImageCube, @1); 1185 } 1186 | IIMAGECUBE { 1187 $$.initialize(EbtIImageCube, @1); 1188 } 1189 | UIMAGECUBE { 1190 $$.initialize(EbtUImageCube, @1); 1191 } 1192 | ATOMICUINT { 1193 $$.initialize(EbtAtomicCounter, @1); 1194 } 1195 | TYPE_NAME { 1196 // This is for user defined type names. The lexical phase looked up the type. 1197 TType& structure = static_cast<TVariable*>($1.symbol)->getType(); 1198 $$.initializeStruct(structure.getStruct(), false, @1); 1199 } 1200 ; 1201 1202 struct_specifier 1203 : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE { 1204 $$ = context->addStructure(@1, @2, $2.string, $5); 1205 } 1206 | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE { 1207 $$ = context->addStructure(@1, @$, NewPoolTString(""), $4); 1208 } 1209 ; 1210 1211 struct_declaration_list 1212 : struct_declaration { 1213 $$ = context->addStructFieldList($1, @1); 1214 } 1215 | struct_declaration_list struct_declaration { 1216 $$ = context->combineStructFieldLists($1, $2, @2); 1217 } 1218 ; 1219 1220 struct_declaration 1221 : type_specifier struct_declarator_list SEMICOLON { 1222 $$ = context->addStructDeclaratorList($1, $2); 1223 } 1224 | type_qualifier type_specifier struct_declarator_list SEMICOLON { 1225 // ES3 Only, but errors should be handled elsewhere 1226 $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3); 1227 } 1228 ; 1229 1230 struct_declarator_list 1231 : struct_declarator { 1232 $$ = NewPoolTFieldList(); 1233 $$->push_back($1); 1234 } 1235 | struct_declarator_list COMMA struct_declarator { 1236 $$->push_back($3); 1237 } 1238 ; 1239 1240 struct_declarator 1241 : identifier { 1242 $$ = context->parseStructDeclarator($1.string, @1); 1243 } 1244 | identifier array_specifier { 1245 $$ = context->parseStructArrayDeclarator($1.string, @1, *($2), @2); 1246 } 1247 ; 1248 1249 initializer 1250 : assignment_expression { $$ = $1; } 1251 ; 1252 1253 declaration_statement 1254 : declaration { $$ = $1; } 1255 ; 1256 1257 statement 1258 : compound_statement_with_scope { $$ = $1; } 1259 | simple_statement { $$ = $1; } 1260 ; 1261 1262 // Grammar Note: Labeled statements for SWITCH only; 'goto' is not supported. 1263 1264 simple_statement 1265 : declaration_statement { $$ = $1; } 1266 | expression_statement { $$ = $1; } 1267 | selection_statement { $$ = $1; } 1268 | switch_statement { $$ = $1; } 1269 | case_label { $$ = $1; } 1270 | iteration_statement { $$ = $1; } 1271 | jump_statement { $$ = $1; } 1272 ; 1273 1274 compound_statement_with_scope 1275 : LEFT_BRACE RIGHT_BRACE { 1276 $$ = new TIntermBlock(); 1277 $$->setLine(@$); 1278 } 1279 | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { 1280 $3->setLine(@$); 1281 $$ = $3; 1282 } 1283 ; 1284 1285 statement_no_new_scope 1286 : compound_statement_no_new_scope { $$ = $1; } 1287 | simple_statement { $$ = $1; } 1288 ; 1289 1290 statement_with_scope 1291 : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; } 1292 | { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; } 1293 ; 1294 1295 compound_statement_no_new_scope 1296 // Statement that doesn't create a new scope for iteration_statement, function definition (scope is created for parameters) 1297 : LEFT_BRACE RIGHT_BRACE { 1298 $$ = new TIntermBlock(); 1299 $$->setLine(@$); 1300 } 1301 | LEFT_BRACE statement_list RIGHT_BRACE { 1302 $2->setLine(@$); 1303 $$ = $2; 1304 } 1305 ; 1306 1307 statement_list 1308 : statement { 1309 $$ = new TIntermBlock(); 1310 $$->appendStatement($1); 1311 } 1312 | statement_list statement { 1313 $$ = $1; 1314 $$->appendStatement($2); 1315 } 1316 ; 1317 1318 expression_statement 1319 : SEMICOLON { $$ = context->addEmptyStatement(@$); } 1320 | expression SEMICOLON { $$ = $1; } 1321 ; 1322 1323 selection_statement 1324 : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { 1325 $$ = context->addIfElse($3, $5, @1); 1326 } 1327 ; 1328 1329 selection_rest_statement 1330 : statement_with_scope ELSE statement_with_scope { 1331 $$.node1 = $1; 1332 $$.node2 = $3; 1333 } 1334 | statement_with_scope { 1335 $$.node1 = $1; 1336 $$.node2 = nullptr; 1337 } 1338 ; 1339 1340 // Note that we've diverged from the spec grammar here a bit for the sake of simplicity. 1341 // We're reusing compound_statement_with_scope instead of having separate rules for switch. 1342 switch_statement 1343 : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement_with_scope { 1344 $$ = context->addSwitch($3, $6, @1); 1345 context->decrSwitchNestingLevel(); 1346 } 1347 ; 1348 1349 case_label 1350 : CASE constant_expression COLON { 1351 $$ = context->addCase($2, @1); 1352 } 1353 | DEFAULT COLON { 1354 $$ = context->addDefault(@1); 1355 } 1356 ; 1357 1358 condition 1359 : expression { 1360 $$ = $1; 1361 context->checkIsScalarBool($1->getLine(), $1); 1362 } 1363 | fully_specified_type identifier EQUAL initializer { 1364 $$ = context->addConditionInitializer($1, *$2.string, $4, @2); 1365 } 1366 ; 1367 1368 iteration_statement 1369 : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } condition RIGHT_PAREN statement_no_new_scope { 1370 context->symbolTable.pop(); 1371 $$ = context->addLoop(ELoopWhile, 0, $4, 0, $6, @1); 1372 context->decrLoopNestingLevel(); 1373 } 1374 | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { 1375 $$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); 1376 context->decrLoopNestingLevel(); 1377 } 1378 | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { 1379 context->symbolTable.pop(); 1380 $$ = context->addLoop(ELoopFor, $4, $5.node1, reinterpret_cast<TIntermTyped*>($5.node2), $7, @1); 1381 context->decrLoopNestingLevel(); 1382 } 1383 ; 1384 1385 for_init_statement 1386 : expression_statement { 1387 $$ = $1; 1388 } 1389 | declaration_statement { 1390 $$ = $1; 1391 } 1392 ; 1393 1394 conditionopt 1395 : condition { 1396 $$ = $1; 1397 } 1398 | /* May be null */ { 1399 $$ = nullptr; 1400 } 1401 ; 1402 1403 for_rest_statement 1404 : conditionopt SEMICOLON { 1405 $$.node1 = $1; 1406 $$.node2 = 0; 1407 } 1408 | conditionopt SEMICOLON expression { 1409 $$.node1 = $1; 1410 $$.node2 = $3; 1411 } 1412 ; 1413 1414 jump_statement 1415 : CONTINUE SEMICOLON { 1416 $$ = context->addBranch(EOpContinue, @1); 1417 } 1418 | BREAK SEMICOLON { 1419 $$ = context->addBranch(EOpBreak, @1); 1420 } 1421 | RETURN SEMICOLON { 1422 $$ = context->addBranch(EOpReturn, @1); 1423 } 1424 | RETURN expression SEMICOLON { 1425 $$ = context->addBranch(EOpReturn, $2, @1); 1426 } 1427 | DISCARD SEMICOLON { 1428 $$ = context->addBranch(EOpKill, @1); 1429 } 1430 ; 1431 1432 // Grammar Note: No 'goto'. Gotos are not supported. 1433 1434 translation_unit 1435 : external_declaration { 1436 $$ = new TIntermBlock(); 1437 $$->setLine(@$); 1438 $$->appendStatement($1); 1439 context->setTreeRoot($$); 1440 } 1441 | translation_unit external_declaration { 1442 $$->appendStatement($2); 1443 } 1444 ; 1445 1446 external_declaration 1447 : function_definition { 1448 $$ = $1; 1449 } 1450 | declaration { 1451 $$ = $1; 1452 } 1453 ; 1454 1455 function_definition 1456 : function_prototype { 1457 context->parseFunctionDefinitionHeader(@1, &($1.function), &($1.intermFunctionPrototype)); 1458 } 1459 compound_statement_no_new_scope { 1460 $$ = context->addFunctionDefinition($1.intermFunctionPrototype, $3, @1); 1461 } 1462 ; 1463 1464 %% 1465 1466 int glslang_parse(TParseContext* context) { 1467 return yyparse(context, context->getScanner()); 1468 } 1469