1 /* 2 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 This file contains the Yacc grammar for GLSL ES. 17 Based on ANSI C Yacc grammar: 18 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html 19 20 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, 21 WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). 22 */ 23 24 %{ 25 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 26 // 27 // Licensed under the Apache License, Version 2.0 (the "License"); 28 // you may not use this file except in compliance with the License. 29 // You may obtain a copy of the License at 30 // 31 // http://www.apache.org/licenses/LICENSE-2.0 32 // 33 // Unless required by applicable law or agreed to in writing, software 34 // distributed under the License is distributed on an "AS IS" BASIS, 35 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 // See the License for the specific language governing permissions and 37 // limitations under the License. 38 39 // This file is auto-generated by generate_parser.sh. DO NOT EDIT! 40 41 // Ignore errors in auto-generated code. 42 #if defined(__GNUC__) 43 #pragma GCC diagnostic ignored "-Wunused-function" 44 #pragma GCC diagnostic ignored "-Wunused-variable" 45 #pragma GCC diagnostic ignored "-Wswitch-enum" 46 #elif defined(_MSC_VER) 47 #pragma warning(disable: 4065) 48 #pragma warning(disable: 4189) 49 #pragma warning(disable: 4505) 50 #pragma warning(disable: 4701) 51 #endif 52 53 #include "SymbolTable.h" 54 #include "ParseHelper.h" 55 56 #define YYENABLE_NLS 0 57 %} 58 59 %expect 1 /* One shift reduce conflict because of if | else */ 60 %pure-parser 61 %parse-param {TParseContext* context} 62 %param {void* yyscanner} 63 64 %code requires { 65 #define YYLTYPE TSourceLoc 66 #define YYLTYPE_IS_DECLARED 1 67 } 68 69 %union { 70 struct { 71 union { 72 TString *string; 73 float f; 74 int i; 75 unsigned int u; 76 bool b; 77 }; 78 TSymbol* symbol; 79 } lex; 80 struct { 81 TOperator op; 82 union { 83 TIntermNode* intermNode; 84 TIntermNodePair nodePair; 85 TIntermTyped* intermTypedNode; 86 TIntermAggregate* intermAggregate; 87 TIntermSwitch* intermSwitch; 88 TIntermCase* intermCase; 89 }; 90 union { 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 }; 100 } interm; 101 } 102 103 %{ 104 extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner); 105 extern void yyerror(YYLTYPE* lloc, TParseContext* context, void* scanner, const char* reason); 106 107 #define YYLLOC_DEFAULT(Current, Rhs, N) \ 108 do { \ 109 if (N) { \ 110 (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \ 111 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ 112 (Current).last_file = YYRHSLOC(Rhs, N).last_file; \ 113 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ 114 } \ 115 else { \ 116 (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \ 117 (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ 118 (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \ 119 (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \ 120 } \ 121 } while (0) 122 123 #define FRAG_VERT_ONLY(S, L) { \ 124 if (context->getShaderType() != GL_FRAGMENT_SHADER && \ 125 context->getShaderType() != GL_VERTEX_SHADER) { \ 126 context->error(L, " supported in vertex/fragment shaders only ", S); \ 127 context->recover(); \ 128 } \ 129 } 130 131 #define VERTEX_ONLY(S, L) { \ 132 if (context->getShaderType() != GL_VERTEX_SHADER) { \ 133 context->error(L, " supported in vertex shaders only ", S); \ 134 context->recover(); \ 135 } \ 136 } 137 138 #define FRAG_ONLY(S, L) { \ 139 if (context->getShaderType() != GL_FRAGMENT_SHADER) { \ 140 context->error(L, " supported in fragment shaders only ", S); \ 141 context->recover(); \ 142 } \ 143 } 144 145 #define ES2_ONLY(S, L) { \ 146 if (context->getShaderVersion() != 100) { \ 147 context->error(L, " supported in GLSL ES 1.00 only ", S); \ 148 context->recover(); \ 149 } \ 150 } 151 152 #define ES3_ONLY(TOKEN, LINE, REASON) { \ 153 if (context->getShaderVersion() != 300) { \ 154 context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ 155 context->recover(); \ 156 } \ 157 } 158 %} 159 160 %token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION 161 %token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE 162 %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT 163 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4 164 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING 165 %token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3 166 %token <lex> CENTROID FLAT SMOOTH 167 %token <lex> STRUCT VOID_TYPE WHILE 168 %token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY 169 %token <lex> ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY 170 %token <lex> USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY 171 %token <lex> SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW 172 %token <lex> LAYOUT 173 174 %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT 175 %token <lex> FIELD_SELECTION 176 %token <lex> LEFT_OP RIGHT_OP 177 %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP 178 %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN 179 %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN 180 %token <lex> SUB_ASSIGN 181 182 %token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT 183 %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT 184 %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION 185 186 %type <interm> assignment_operator unary_operator 187 %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression 188 %type <interm.intermTypedNode> expression integer_expression assignment_expression 189 %type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression 190 %type <interm.intermTypedNode> relational_expression equality_expression 191 %type <interm.intermTypedNode> conditional_expression constant_expression 192 %type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression 193 %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression 194 %type <interm.intermTypedNode> function_call initializer condition conditionopt 195 196 %type <interm.intermNode> translation_unit function_definition 197 %type <interm.intermNode> statement simple_statement 198 %type <interm.intermAggregate> statement_list compound_statement compound_statement_no_new_scope 199 %type <interm.intermNode> declaration_statement selection_statement expression_statement 200 %type <interm.intermNode> declaration external_declaration 201 %type <interm.intermNode> for_init_statement 202 %type <interm.nodePair> selection_rest_statement for_rest_statement 203 %type <interm.intermSwitch> switch_statement 204 %type <interm.intermCase> case_label 205 %type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope 206 %type <interm> single_declaration init_declarator_list 207 208 %type <interm> parameter_declaration parameter_declarator parameter_type_specifier 209 %type <interm.qualifier> parameter_qualifier parameter_type_qualifier 210 %type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id 211 212 %type <interm.precision> precision_qualifier 213 %type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier 214 %type <interm.type> type_specifier_no_prec type_specifier_nonarray 215 %type <interm.type> struct_specifier 216 %type <interm.field> struct_declarator 217 %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list 218 %type <interm.function> function_header function_declarator function_identifier 219 %type <interm.function> function_header_with_parameters function_call_header 220 %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype 221 %type <interm> function_call_or_method 222 223 %type <lex> enter_struct 224 225 %start translation_unit 226 %% 227 228 variable_identifier 229 : IDENTIFIER { 230 // The symbol table search was done in the lexical phase 231 const TVariable *variable = context->getNamedVariable(@1, $1.string, $1.symbol); 232 233 // don't delete $1.string, it's used by error recovery, and the pool 234 // pop will reclaim the memory 235 236 ConstantUnion *constArray = variable->getConstPointer(); 237 if (constArray) { 238 TType t(variable->getType()); 239 $$ = context->intermediate.addConstantUnion(constArray, t, @1); 240 } else 241 $$ = context->intermediate.addSymbol(variable->getUniqueId(), 242 variable->getName(), 243 variable->getType(), @1); 244 } 245 ; 246 247 primary_expression 248 : variable_identifier { 249 $$ = $1; 250 } 251 | INTCONSTANT { 252 ConstantUnion *unionArray = new ConstantUnion[1]; 253 unionArray->setIConst($1.i); 254 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), @1); 255 } 256 | UINTCONSTANT { 257 ConstantUnion *unionArray = new ConstantUnion[1]; 258 unionArray->setUConst($1.u); 259 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtUInt, EbpUndefined, EvqConstExpr), @1); 260 } 261 | FLOATCONSTANT { 262 ConstantUnion *unionArray = new ConstantUnion[1]; 263 unionArray->setFConst($1.f); 264 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConstExpr), @1); 265 } 266 | BOOLCONSTANT { 267 ConstantUnion *unionArray = new ConstantUnion[1]; 268 unionArray->setBConst($1.b); 269 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConstExpr), @1); 270 } 271 | LEFT_PAREN expression RIGHT_PAREN { 272 $$ = $2; 273 } 274 ; 275 276 postfix_expression 277 : primary_expression { 278 $$ = $1; 279 } 280 | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { 281 $$ = context->addIndexExpression($1, @2, $3); 282 } 283 | function_call { 284 $$ = $1; 285 } 286 | postfix_expression DOT FIELD_SELECTION { 287 $$ = context->addFieldSelectionExpression($1, @2, *$3.string, @3); 288 } 289 | postfix_expression INC_OP { 290 $$ = context->addUnaryMathLValue(EOpPostIncrement, $1, @2); 291 } 292 | postfix_expression DEC_OP { 293 $$ = context->addUnaryMathLValue(EOpPostDecrement, $1, @2); 294 } 295 ; 296 297 integer_expression 298 : expression { 299 if (context->integerErrorCheck($1, "[]")) 300 context->recover(); 301 $$ = $1; 302 } 303 ; 304 305 function_call 306 : function_call_or_method { 307 bool fatalError = false; 308 $$ = context->addFunctionCallOrMethod($1.function, $1.nodePair.node1, $1.nodePair.node2, @1, &fatalError); 309 if (fatalError) 310 { 311 YYERROR; 312 } 313 } 314 ; 315 316 function_call_or_method 317 : function_call_generic { 318 $$ = $1; 319 $$.nodePair.node2 = nullptr; 320 } 321 | postfix_expression DOT function_call_generic { 322 ES3_ONLY("", @3, "methods"); 323 $$ = $3; 324 $$.nodePair.node2 = $1; 325 } 326 ; 327 328 function_call_generic 329 : function_call_header_with_parameters RIGHT_PAREN { 330 $$ = $1; 331 } 332 | function_call_header_no_parameters RIGHT_PAREN { 333 $$ = $1; 334 } 335 ; 336 337 function_call_header_no_parameters 338 : function_call_header VOID_TYPE { 339 $$.function = $1; 340 $$.nodePair.node1 = nullptr; 341 } 342 | function_call_header { 343 $$.function = $1; 344 $$.nodePair.node1 = nullptr; 345 } 346 ; 347 348 function_call_header_with_parameters 349 : function_call_header assignment_expression { 350 TParameter param = { 0, new TType($2->getType()) }; 351 $1->addParameter(param); 352 $$.function = $1; 353 $$.nodePair.node1 = $2; 354 } 355 | function_call_header_with_parameters COMMA assignment_expression { 356 TParameter param = { 0, new TType($3->getType()) }; 357 $1.function->addParameter(param); 358 $$.function = $1.function; 359 $$.nodePair.node1 = context->intermediate.growAggregate($1.intermNode, $3, @2); 360 } 361 ; 362 363 function_call_header 364 : function_identifier LEFT_PAREN { 365 $$ = $1; 366 } 367 ; 368 369 // Grammar Note: Constructors look like functions, but are recognized as types. 370 371 function_identifier 372 : type_specifier_no_prec { 373 if ($1.array) { 374 ES3_ONLY("[]", @1, "array constructor"); 375 } 376 $$ = context->addConstructorFunc($1); 377 } 378 | IDENTIFIER { 379 if (context->reservedErrorCheck(@1, *$1.string)) 380 context->recover(); 381 TType type(EbtVoid, EbpUndefined); 382 TFunction *function = new TFunction($1.string, type); 383 $$ = function; 384 } 385 | FIELD_SELECTION { 386 if (context->reservedErrorCheck(@1, *$1.string)) 387 context->recover(); 388 TType type(EbtVoid, EbpUndefined); 389 TFunction *function = new TFunction($1.string, type); 390 $$ = function; 391 } 392 ; 393 394 unary_expression 395 : postfix_expression { 396 $$ = $1; 397 } 398 | INC_OP unary_expression { 399 $$ = context->addUnaryMathLValue(EOpPreIncrement, $2, @1); 400 } 401 | DEC_OP unary_expression { 402 $$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1); 403 } 404 | unary_operator unary_expression { 405 if ($1.op != EOpNull) { 406 $$ = context->addUnaryMath($1.op, $2, @1); 407 } else 408 $$ = $2; 409 } 410 ; 411 // Grammar Note: No traditional style type casts. 412 413 unary_operator 414 : PLUS { $$.op = EOpNull; } 415 | DASH { $$.op = EOpNegative; } 416 | BANG { $$.op = EOpLogicalNot; } 417 | TILDE { 418 ES3_ONLY("~", @1, "bit-wise operator"); 419 $$.op = 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 FRAG_VERT_ONLY("*", @2); 428 $$ = context->addBinaryMath(EOpMul, $1, $3, @2); 429 } 430 | multiplicative_expression SLASH unary_expression { 431 FRAG_VERT_ONLY("/", @2); 432 $$ = context->addBinaryMath(EOpDiv, $1, $3, @2); 433 } 434 | multiplicative_expression PERCENT unary_expression { 435 FRAG_VERT_ONLY("%", @2); 436 ES3_ONLY("%", @2, "integer modulus operator"); 437 $$ = context->addBinaryMath(EOpIMod, $1, $3, @2); 438 } 439 ; 440 441 additive_expression 442 : multiplicative_expression { $$ = $1; } 443 | additive_expression PLUS multiplicative_expression { 444 $$ = context->addBinaryMath(EOpAdd, $1, $3, @2); 445 } 446 | additive_expression DASH multiplicative_expression { 447 $$ = context->addBinaryMath(EOpSub, $1, $3, @2); 448 } 449 ; 450 451 shift_expression 452 : additive_expression { $$ = $1; } 453 | shift_expression LEFT_OP additive_expression { 454 ES3_ONLY("<<", @2, "bit-wise operator"); 455 $$ = context->addBinaryMath(EOpBitShiftLeft, $1, $3, @2); 456 } 457 | shift_expression RIGHT_OP additive_expression { 458 ES3_ONLY(">>", @2, "bit-wise operator"); 459 $$ = context->addBinaryMath(EOpBitShiftRight, $1, $3, @2); 460 } 461 ; 462 463 relational_expression 464 : shift_expression { $$ = $1; } 465 | relational_expression LEFT_ANGLE shift_expression { 466 $$ = context->addBinaryMathBooleanResult(EOpLessThan, $1, $3, @2); 467 } 468 | relational_expression RIGHT_ANGLE shift_expression { 469 $$ = context->addBinaryMathBooleanResult(EOpGreaterThan, $1, $3, @2); 470 } 471 | relational_expression LE_OP shift_expression { 472 $$ = context->addBinaryMathBooleanResult(EOpLessThanEqual, $1, $3, @2); 473 } 474 | relational_expression GE_OP shift_expression { 475 $$ = context->addBinaryMathBooleanResult(EOpGreaterThanEqual, $1, $3, @2); 476 } 477 ; 478 479 equality_expression 480 : relational_expression { $$ = $1; } 481 | equality_expression EQ_OP relational_expression { 482 $$ = context->addBinaryMathBooleanResult(EOpEqual, $1, $3, @2); 483 } 484 | equality_expression NE_OP relational_expression { 485 $$ = context->addBinaryMathBooleanResult(EOpNotEqual, $1, $3, @2); 486 } 487 ; 488 489 and_expression 490 : equality_expression { $$ = $1; } 491 | and_expression AMPERSAND equality_expression { 492 ES3_ONLY("&", @2, "bit-wise operator"); 493 $$ = context->addBinaryMath(EOpBitwiseAnd, $1, $3, @2); 494 } 495 ; 496 497 exclusive_or_expression 498 : and_expression { $$ = $1; } 499 | exclusive_or_expression CARET and_expression { 500 ES3_ONLY("^", @2, "bit-wise operator"); 501 $$ = context->addBinaryMath(EOpBitwiseXor, $1, $3, @2); 502 } 503 ; 504 505 inclusive_or_expression 506 : exclusive_or_expression { $$ = $1; } 507 | inclusive_or_expression VERTICAL_BAR exclusive_or_expression { 508 ES3_ONLY("|", @2, "bit-wise operator"); 509 $$ = context->addBinaryMath(EOpBitwiseOr, $1, $3, @2); 510 } 511 ; 512 513 logical_and_expression 514 : inclusive_or_expression { $$ = $1; } 515 | logical_and_expression AND_OP inclusive_or_expression { 516 $$ = context->addBinaryMathBooleanResult(EOpLogicalAnd, $1, $3, @2); 517 } 518 ; 519 520 logical_xor_expression 521 : logical_and_expression { $$ = $1; } 522 | logical_xor_expression XOR_OP logical_and_expression { 523 $$ = context->addBinaryMathBooleanResult(EOpLogicalXor, $1, $3, @2); 524 } 525 ; 526 527 logical_or_expression 528 : logical_xor_expression { $$ = $1; } 529 | logical_or_expression OR_OP logical_xor_expression { 530 $$ = context->addBinaryMathBooleanResult(EOpLogicalOr, $1, $3, @2); 531 } 532 ; 533 534 conditional_expression 535 : logical_or_expression { $$ = $1; } 536 | logical_or_expression QUESTION expression COLON assignment_expression { 537 $$ = context->addTernarySelection($1, $3, $5, @2); 538 } 539 ; 540 541 assignment_expression 542 : conditional_expression { $$ = $1; } 543 | unary_expression assignment_operator assignment_expression { 544 if (context->lValueErrorCheck(@2, "assign", $1)) 545 context->recover(); 546 $$ = context->addAssign($2.op, $1, $3, @2); 547 } 548 ; 549 550 assignment_operator 551 : EQUAL { $$.op = EOpAssign; } 552 | MUL_ASSIGN { FRAG_VERT_ONLY("*=", @1); $$.op = EOpMulAssign; } 553 | DIV_ASSIGN { FRAG_VERT_ONLY("/=", @1); $$.op = EOpDivAssign; } 554 | MOD_ASSIGN { ES3_ONLY("%=", @1, "integer modulus operator"); 555 FRAG_VERT_ONLY("%=", @1); $$.op = EOpIModAssign; } 556 | ADD_ASSIGN { $$.op = EOpAddAssign; } 557 | SUB_ASSIGN { $$.op = EOpSubAssign; } 558 | LEFT_ASSIGN { ES3_ONLY("<<=", @1, "bit-wise operator"); 559 FRAG_VERT_ONLY("<<=", @1); 560 $$.op = EOpBitShiftLeftAssign; } 561 | RIGHT_ASSIGN { ES3_ONLY(">>=", @1, "bit-wise operator"); 562 FRAG_VERT_ONLY(">>=", @1); 563 $$.op = EOpBitShiftRightAssign; } 564 | AND_ASSIGN { ES3_ONLY("&=", @1, "bit-wise operator"); 565 FRAG_VERT_ONLY("&=", @1); 566 $$.op = EOpBitwiseAndAssign; } 567 | XOR_ASSIGN { ES3_ONLY("^=", @1, "bit-wise operator"); 568 FRAG_VERT_ONLY("^=", @1); 569 $$.op = EOpBitwiseXorAssign; } 570 | OR_ASSIGN { ES3_ONLY("|=", @1, "bit-wise operator"); 571 FRAG_VERT_ONLY("|=", @1); 572 $$.op = EOpBitwiseOrAssign; } 573 ; 574 575 expression 576 : assignment_expression { 577 $$ = $1; 578 } 579 | expression COMMA assignment_expression { 580 $$ = context->intermediate.addComma($1, $3, @2); 581 if ($$ == 0) { 582 context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString()); 583 context->recover(); 584 $$ = $3; 585 } 586 } 587 ; 588 589 constant_expression 590 : conditional_expression { 591 if (context->constErrorCheck($1)) 592 context->recover(); 593 $$ = $1; 594 } 595 ; 596 597 enter_struct 598 : IDENTIFIER LEFT_BRACE { 599 if (context->enterStructDeclaration(@1, *$1.string)) 600 context->recover(); 601 $$ = $1; 602 } 603 ; 604 605 declaration 606 : function_prototype SEMICOLON { 607 $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1); 608 } 609 | init_declarator_list SEMICOLON { 610 TIntermAggregate *aggNode = $1.intermAggregate; 611 if (aggNode && aggNode->getOp() == EOpNull) 612 aggNode->setOp(EOpDeclaration); 613 $$ = aggNode; 614 } 615 | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { 616 if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { 617 context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type)); 618 context->recover(); 619 } 620 $$ = 0; 621 } 622 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { 623 ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); 624 $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @1, NULL, @1); 625 } 626 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { 627 ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); 628 $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @1); 629 } 630 | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON { 631 ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); 632 $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6); 633 } 634 | type_qualifier SEMICOLON { 635 context->parseGlobalLayoutQualifier($1); 636 $$ = 0; 637 } 638 ; 639 640 function_prototype 641 : function_declarator RIGHT_PAREN { 642 $$.function = context->parseFunctionDeclarator(@2, $1); 643 } 644 ; 645 646 function_declarator 647 : function_header { 648 $$ = $1; 649 } 650 | function_header_with_parameters { 651 $$ = $1; 652 } 653 ; 654 655 656 function_header_with_parameters 657 : function_header parameter_declaration { 658 // Add the parameter 659 $$ = $1; 660 if ($2.param.type->getBasicType() != EbtVoid) 661 $1->addParameter($2.param); 662 else 663 delete $2.param.type; 664 } 665 | function_header_with_parameters COMMA parameter_declaration { 666 // 667 // Only first parameter of one-parameter functions can be void 668 // The check for named parameters not being void is done in parameter_declarator 669 // 670 if ($3.param.type->getBasicType() == EbtVoid) { 671 // 672 // This parameter > first is void 673 // 674 context->error(@2, "cannot be an argument type except for '(void)'", "void"); 675 context->recover(); 676 delete $3.param.type; 677 } else { 678 // Add the parameter 679 $$ = $1; 680 $1->addParameter($3.param); 681 } 682 } 683 ; 684 685 function_header 686 : fully_specified_type IDENTIFIER LEFT_PAREN { 687 if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { 688 context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier)); 689 context->recover(); 690 } 691 if (!$1.layoutQualifier.isEmpty()) 692 { 693 context->error(@2, "no qualifiers allowed for function return", "layout"); 694 context->recover(); 695 } 696 // make sure a sampler is not involved as well... 697 if (context->samplerErrorCheck(@2, $1, "samplers can't be function return values")) 698 context->recover(); 699 700 // Add the function as a prototype after parsing it (we do not support recursion) 701 TFunction *function; 702 TType type($1); 703 function = new TFunction($2.string, type); 704 $$ = function; 705 706 context->symbolTable.push(); 707 } 708 ; 709 710 parameter_declarator 711 // Type + name 712 : type_specifier IDENTIFIER { 713 if ($1.type == EbtVoid) { 714 context->error(@2, "illegal use of type 'void'", $2.string->c_str()); 715 context->recover(); 716 } 717 if (context->reservedErrorCheck(@2, *$2.string)) 718 context->recover(); 719 TParameter param = {$2.string, new TType($1)}; 720 $$.param = param; 721 } 722 | type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { 723 // Check that we can make an array out of this type 724 if (context->arrayTypeErrorCheck(@3, $1)) 725 context->recover(); 726 727 if (context->reservedErrorCheck(@2, *$2.string)) 728 context->recover(); 729 730 int size; 731 if (context->arraySizeErrorCheck(@3, $4, size)) 732 context->recover(); 733 $1.setArray(true, size); 734 735 TType* type = new TType($1); 736 TParameter param = { $2.string, type }; 737 $$.param = param; 738 } 739 ; 740 741 parameter_declaration 742 // 743 // The only parameter qualifier a parameter can have are 744 // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST. 745 // 746 747 // 748 // Type + name 749 // 750 : parameter_type_qualifier parameter_qualifier parameter_declarator { 751 $$ = $3; 752 if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) 753 context->recover(); 754 } 755 | parameter_qualifier parameter_declarator { 756 $$ = $2; 757 if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) 758 context->recover(); 759 if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) 760 context->recover(); 761 } 762 // 763 // Only type 764 // 765 | parameter_type_qualifier parameter_qualifier parameter_type_specifier { 766 $$ = $3; 767 if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) 768 context->recover(); 769 } 770 | parameter_qualifier parameter_type_specifier { 771 $$ = $2; 772 if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) 773 context->recover(); 774 if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) 775 context->recover(); 776 } 777 ; 778 779 parameter_qualifier 780 : /* empty */ { 781 $$ = EvqIn; 782 } 783 | IN_QUAL { 784 $$ = EvqIn; 785 } 786 | OUT_QUAL { 787 $$ = EvqOut; 788 } 789 | INOUT_QUAL { 790 $$ = EvqInOut; 791 } 792 ; 793 794 parameter_type_specifier 795 : type_specifier { 796 TParameter param = { 0, new TType($1) }; 797 $$.param = param; 798 } 799 ; 800 801 init_declarator_list 802 : single_declaration { 803 $$ = $1; 804 } 805 | init_declarator_list COMMA IDENTIFIER { 806 $$ = $1; 807 $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, @3, *$3.string); 808 } 809 | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { 810 $$ = $1; 811 $$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); 812 } 813 | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { 814 ES3_ONLY("[]", @3, "implicitly sized array"); 815 $$ = $1; 816 $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, nullptr, @6, $7); 817 } 818 | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { 819 ES3_ONLY("=", @7, "first-class arrays (array initializer)"); 820 $$ = $1; 821 $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8); 822 } 823 | init_declarator_list COMMA IDENTIFIER EQUAL initializer { 824 $$ = $1; 825 $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); 826 } 827 ; 828 829 single_declaration 830 : fully_specified_type { 831 $$.type = $1; 832 $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, ""); 833 } 834 | fully_specified_type IDENTIFIER { 835 $$.type = $1; 836 $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); 837 } 838 | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { 839 $$.type = $1; 840 $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); 841 } 842 | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { 843 ES3_ONLY("[]", @3, "implicitly sized array"); 844 $$.type = $1; 845 $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6); 846 } 847 | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { 848 ES3_ONLY("=", @6, "first-class arrays (array initializer)"); 849 $$.type = $1; 850 $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7); 851 } 852 | fully_specified_type IDENTIFIER EQUAL initializer { 853 $$.type = $1; 854 $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); 855 } 856 | INVARIANT IDENTIFIER { 857 // $$.type is not used in invariant declarations. 858 $$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol); 859 } 860 ; 861 862 fully_specified_type 863 : type_specifier { 864 $$ = $1; 865 866 if ($1.array) { 867 ES3_ONLY("[]", @1, "first-class-array"); 868 if (context->getShaderVersion() != 300) { 869 $1.clearArrayness(); 870 } 871 } 872 } 873 | type_qualifier type_specifier { 874 $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2); 875 } 876 ; 877 878 interpolation_qualifier 879 : SMOOTH { 880 $$.qualifier = EvqSmooth; 881 } 882 | FLAT { 883 $$.qualifier = EvqFlat; 884 } 885 ; 886 887 parameter_type_qualifier 888 : CONST_QUAL { 889 $$ = EvqConstReadOnly; 890 } 891 ; 892 893 type_qualifier 894 : ATTRIBUTE { 895 VERTEX_ONLY("attribute", @1); 896 ES2_ONLY("attribute", @1); 897 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute")) 898 context->recover(); 899 $$.setBasic(EbtVoid, EvqAttribute, @1); 900 } 901 | VARYING { 902 ES2_ONLY("varying", @1); 903 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) 904 context->recover(); 905 if (context->getShaderType() == GL_VERTEX_SHADER) 906 $$.setBasic(EbtVoid, EvqVaryingOut, @1); 907 else 908 $$.setBasic(EbtVoid, EvqVaryingIn, @1); 909 } 910 | INVARIANT VARYING { 911 ES2_ONLY("varying", @1); 912 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) 913 context->recover(); 914 if (context->getShaderType() == GL_VERTEX_SHADER) 915 $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1); 916 else 917 $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1); 918 } 919 | storage_qualifier { 920 if ($1.qualifier != EvqConstExpr && !context->symbolTable.atGlobalLevel()) 921 { 922 context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); 923 context->recover(); 924 } 925 $$.setBasic(EbtVoid, $1.qualifier, @1); 926 } 927 | interpolation_qualifier storage_qualifier { 928 $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier); 929 } 930 | interpolation_qualifier { 931 context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString($1.qualifier)); 932 context->recover(); 933 934 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 935 $$.setBasic(EbtVoid, qual, @1); 936 } 937 | layout_qualifier { 938 $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 939 $$.layoutQualifier = $1; 940 } 941 | layout_qualifier storage_qualifier { 942 $$.setBasic(EbtVoid, $2.qualifier, @2); 943 $$.layoutQualifier = $1; 944 } 945 | INVARIANT storage_qualifier { 946 context->es3InvariantErrorCheck($2.qualifier, @1); 947 $$.setBasic(EbtVoid, $2.qualifier, @2); 948 $$.invariant = true; 949 } 950 | INVARIANT interpolation_qualifier storage_qualifier { 951 context->es3InvariantErrorCheck($3.qualifier, @1); 952 $$ = context->joinInterpolationQualifiers(@2, $2.qualifier, @3, $3.qualifier); 953 $$.invariant = true; 954 } 955 ; 956 957 storage_qualifier 958 : CONST_QUAL { 959 $$.qualifier = EvqConstExpr; 960 } 961 | IN_QUAL { 962 ES3_ONLY("in", @1, "storage qualifier"); 963 $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; 964 } 965 | OUT_QUAL { 966 ES3_ONLY("out", @1, "storage qualifier"); 967 $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; 968 } 969 | CENTROID IN_QUAL { 970 ES3_ONLY("centroid in", @1, "storage qualifier"); 971 if (context->getShaderType() == GL_VERTEX_SHADER) 972 { 973 context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); 974 context->recover(); 975 } 976 $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; 977 } 978 | CENTROID OUT_QUAL { 979 ES3_ONLY("centroid out", @1, "storage qualifier"); 980 if (context->getShaderType() == GL_FRAGMENT_SHADER) 981 { 982 context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); 983 context->recover(); 984 } 985 $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; 986 } 987 | UNIFORM { 988 if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) 989 context->recover(); 990 $$.qualifier = EvqUniform; 991 } 992 ; 993 994 type_specifier 995 : type_specifier_no_prec { 996 $$ = $1; 997 998 if ($$.precision == EbpUndefined) { 999 $$.precision = context->symbolTable.getDefaultPrecision($1.type); 1000 if (context->precisionErrorCheck(@1, $$.precision, $1.type)) { 1001 context->recover(); 1002 } 1003 } 1004 } 1005 | precision_qualifier type_specifier_no_prec { 1006 $$ = $2; 1007 $$.precision = $1; 1008 1009 if (!SupportsPrecision($2.type)) { 1010 context->error(@1, "illegal type for precision qualifier", getBasicString($2.type)); 1011 context->recover(); 1012 } 1013 } 1014 ; 1015 1016 precision_qualifier 1017 : HIGH_PRECISION { 1018 $$ = EbpHigh; 1019 } 1020 | MEDIUM_PRECISION { 1021 $$ = EbpMedium; 1022 } 1023 | LOW_PRECISION { 1024 $$ = EbpLow; 1025 } 1026 ; 1027 1028 layout_qualifier 1029 : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { 1030 ES3_ONLY("layout", @1, "qualifier"); 1031 $$ = $3; 1032 } 1033 ; 1034 1035 layout_qualifier_id_list 1036 : layout_qualifier_id { 1037 $$ = $1; 1038 } 1039 | layout_qualifier_id_list COMMA layout_qualifier_id { 1040 $$ = context->joinLayoutQualifiers($1, $3); 1041 } 1042 ; 1043 1044 layout_qualifier_id 1045 : IDENTIFIER { 1046 $$ = context->parseLayoutQualifier(*$1.string, @1); 1047 } 1048 | IDENTIFIER EQUAL INTCONSTANT { 1049 $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); 1050 } 1051 | IDENTIFIER EQUAL UINTCONSTANT { 1052 $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); 1053 } 1054 ; 1055 1056 type_specifier_no_prec 1057 : type_specifier_nonarray { 1058 $$ = $1; 1059 } 1060 | type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET { 1061 ES3_ONLY("[]", @2, "implicitly sized array"); 1062 $$ = $1; 1063 $$.setArray(true, 0); 1064 } 1065 | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { 1066 $$ = $1; 1067 1068 if (context->arrayTypeErrorCheck(@2, $1)) 1069 context->recover(); 1070 else { 1071 int size; 1072 if (context->arraySizeErrorCheck(@2, $3, size)) 1073 context->recover(); 1074 $$.setArray(true, size); 1075 } 1076 } 1077 ; 1078 1079 type_specifier_nonarray 1080 : VOID_TYPE { 1081 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1082 $$.setBasic(EbtVoid, qual, @1); 1083 } 1084 | FLOAT_TYPE { 1085 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1086 $$.setBasic(EbtFloat, qual, @1); 1087 } 1088 | INT_TYPE { 1089 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1090 $$.setBasic(EbtInt, qual, @1); 1091 } 1092 | UINT_TYPE { 1093 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1094 $$.setBasic(EbtUInt, qual, @1); 1095 } 1096 | BOOL_TYPE { 1097 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1098 $$.setBasic(EbtBool, qual, @1); 1099 } 1100 | VEC2 { 1101 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1102 $$.setBasic(EbtFloat, qual, @1); 1103 $$.setAggregate(2); 1104 } 1105 | VEC3 { 1106 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1107 $$.setBasic(EbtFloat, qual, @1); 1108 $$.setAggregate(3); 1109 } 1110 | VEC4 { 1111 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1112 $$.setBasic(EbtFloat, qual, @1); 1113 $$.setAggregate(4); 1114 } 1115 | BVEC2 { 1116 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1117 $$.setBasic(EbtBool, qual, @1); 1118 $$.setAggregate(2); 1119 } 1120 | BVEC3 { 1121 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1122 $$.setBasic(EbtBool, qual, @1); 1123 $$.setAggregate(3); 1124 } 1125 | BVEC4 { 1126 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1127 $$.setBasic(EbtBool, qual, @1); 1128 $$.setAggregate(4); 1129 } 1130 | IVEC2 { 1131 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1132 $$.setBasic(EbtInt, qual, @1); 1133 $$.setAggregate(2); 1134 } 1135 | IVEC3 { 1136 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1137 $$.setBasic(EbtInt, qual, @1); 1138 $$.setAggregate(3); 1139 } 1140 | IVEC4 { 1141 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1142 $$.setBasic(EbtInt, qual, @1); 1143 $$.setAggregate(4); 1144 } 1145 | UVEC2 { 1146 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1147 $$.setBasic(EbtUInt, qual, @1); 1148 $$.setAggregate(2); 1149 } 1150 | UVEC3 { 1151 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1152 $$.setBasic(EbtUInt, qual, @1); 1153 $$.setAggregate(3); 1154 } 1155 | UVEC4 { 1156 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1157 $$.setBasic(EbtUInt, qual, @1); 1158 $$.setAggregate(4); 1159 } 1160 | MATRIX2 { 1161 FRAG_VERT_ONLY("mat2", @1); 1162 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1163 $$.setBasic(EbtFloat, qual, @1); 1164 $$.setMatrix(2, 2); 1165 } 1166 | MATRIX3 { 1167 FRAG_VERT_ONLY("mat3", @1); 1168 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1169 $$.setBasic(EbtFloat, qual, @1); 1170 $$.setMatrix(3, 3); 1171 } 1172 | MATRIX4 { 1173 FRAG_VERT_ONLY("mat4", @1); 1174 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1175 $$.setBasic(EbtFloat, qual, @1); 1176 $$.setMatrix(4, 4); 1177 } 1178 | MATRIX2x3 { 1179 FRAG_VERT_ONLY("mat2x3", @1); 1180 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1181 $$.setBasic(EbtFloat, qual, @1); 1182 $$.setMatrix(2, 3); 1183 } 1184 | MATRIX3x2 { 1185 FRAG_VERT_ONLY("mat3x2", @1); 1186 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1187 $$.setBasic(EbtFloat, qual, @1); 1188 $$.setMatrix(3, 2); 1189 } 1190 | MATRIX2x4 { 1191 FRAG_VERT_ONLY("mat2x4", @1); 1192 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1193 $$.setBasic(EbtFloat, qual, @1); 1194 $$.setMatrix(2, 4); 1195 } 1196 | MATRIX4x2 { 1197 FRAG_VERT_ONLY("mat4x2", @1); 1198 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1199 $$.setBasic(EbtFloat, qual, @1); 1200 $$.setMatrix(4, 2); 1201 } 1202 | MATRIX3x4 { 1203 FRAG_VERT_ONLY("mat3x4", @1); 1204 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1205 $$.setBasic(EbtFloat, qual, @1); 1206 $$.setMatrix(3, 4); 1207 } 1208 | MATRIX4x3 { 1209 FRAG_VERT_ONLY("mat4x3", @1); 1210 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1211 $$.setBasic(EbtFloat, qual, @1); 1212 $$.setMatrix(4, 3); 1213 } 1214 | SAMPLER2D { 1215 FRAG_VERT_ONLY("sampler2D", @1); 1216 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1217 $$.setBasic(EbtSampler2D, qual, @1); 1218 } 1219 | SAMPLERCUBE { 1220 FRAG_VERT_ONLY("samplerCube", @1); 1221 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1222 $$.setBasic(EbtSamplerCube, qual, @1); 1223 } 1224 | SAMPLER_EXTERNAL_OES { 1225 if (!context->supportsExtension("GL_OES_EGL_image_external")) { 1226 context->error(@1, "unsupported type", "samplerExternalOES", ""); 1227 context->recover(); 1228 } 1229 FRAG_VERT_ONLY("samplerExternalOES", @1); 1230 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1231 $$.setBasic(EbtSamplerExternalOES, qual, @1); 1232 } 1233 | SAMPLER3D { 1234 FRAG_VERT_ONLY("sampler3D", @1); 1235 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1236 $$.setBasic(EbtSampler3D, qual, @1); 1237 } 1238 | SAMPLER2DARRAY { 1239 FRAG_VERT_ONLY("sampler2DArray", @1); 1240 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1241 $$.setBasic(EbtSampler2DArray, qual, @1); 1242 } 1243 | ISAMPLER2D { 1244 FRAG_VERT_ONLY("isampler2D", @1); 1245 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1246 $$.setBasic(EbtISampler2D, qual, @1); 1247 } 1248 | ISAMPLER3D { 1249 FRAG_VERT_ONLY("isampler3D", @1); 1250 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1251 $$.setBasic(EbtISampler3D, qual, @1); 1252 } 1253 | ISAMPLERCUBE { 1254 FRAG_VERT_ONLY("isamplerCube", @1); 1255 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1256 $$.setBasic(EbtISamplerCube, qual, @1); 1257 } 1258 | ISAMPLER2DARRAY { 1259 FRAG_VERT_ONLY("isampler2DArray", @1); 1260 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1261 $$.setBasic(EbtISampler2DArray, qual, @1); 1262 } 1263 | USAMPLER2D { 1264 FRAG_VERT_ONLY("usampler2D", @1); 1265 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1266 $$.setBasic(EbtUSampler2D, qual, @1); 1267 } 1268 | USAMPLER3D { 1269 FRAG_VERT_ONLY("usampler3D", @1); 1270 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1271 $$.setBasic(EbtUSampler3D, qual, @1); 1272 } 1273 | USAMPLERCUBE { 1274 FRAG_VERT_ONLY("usamplerCube", @1); 1275 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1276 $$.setBasic(EbtUSamplerCube, qual, @1); 1277 } 1278 | USAMPLER2DARRAY { 1279 FRAG_VERT_ONLY("usampler2DArray", @1); 1280 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1281 $$.setBasic(EbtUSampler2DArray, qual, @1); 1282 } 1283 | SAMPLER2DSHADOW { 1284 FRAG_VERT_ONLY("sampler2DShadow", @1); 1285 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1286 $$.setBasic(EbtSampler2DShadow, qual, @1); 1287 } 1288 | SAMPLERCUBESHADOW { 1289 FRAG_VERT_ONLY("samplerCubeShadow", @1); 1290 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1291 $$.setBasic(EbtSamplerCubeShadow, qual, @1); 1292 } 1293 | SAMPLER2DARRAYSHADOW { 1294 FRAG_VERT_ONLY("sampler2DArrayShadow", @1); 1295 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1296 $$.setBasic(EbtSampler2DArrayShadow, qual, @1); 1297 } 1298 | struct_specifier { 1299 FRAG_VERT_ONLY("struct", @1); 1300 $$ = $1; 1301 $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1302 } 1303 | TYPE_NAME { 1304 // 1305 // This is for user defined type names. The lexical phase looked up the 1306 // type. 1307 // 1308 TType& structure = static_cast<TVariable*>($1.symbol)->getType(); 1309 TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; 1310 $$.setBasic(EbtStruct, qual, @1); 1311 $$.userDef = &structure; 1312 } 1313 ; 1314 1315 struct_specifier 1316 : STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { 1317 $$ = context->addStructure(@1, @2, $2.string, $5); 1318 } 1319 | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { 1320 $$ = context->addStructure(@1, @1, NewPoolTString(""), $4); 1321 } 1322 ; 1323 1324 struct_declaration_list 1325 : struct_declaration { 1326 $$ = $1; 1327 } 1328 | struct_declaration_list struct_declaration { 1329 $$ = $1; 1330 for (unsigned int i = 0; i < $2->size(); ++i) { 1331 TField* field = (*$2)[i]; 1332 for (unsigned int j = 0; j < $$->size(); ++j) { 1333 if ((*$$)[j]->name() == field->name()) { 1334 context->error((*$2)[i]->line(), "duplicate field name in structure:", "struct", field->name().c_str()); 1335 context->recover(); 1336 } 1337 } 1338 $$->push_back((*$2)[i]); 1339 } 1340 } 1341 ; 1342 1343 struct_declaration 1344 : type_specifier struct_declarator_list SEMICOLON { 1345 $$ = context->addStructDeclaratorList($1, $2); 1346 } 1347 | type_qualifier type_specifier struct_declarator_list SEMICOLON { 1348 // ES3 Only, but errors should be handled elsewhere 1349 $2.qualifier = $1.qualifier; 1350 $2.layoutQualifier = $1.layoutQualifier; 1351 $$ = context->addStructDeclaratorList($2, $3); 1352 } 1353 ; 1354 1355 struct_declarator_list 1356 : struct_declarator { 1357 $$ = NewPoolTFieldList(); 1358 $$->push_back($1); 1359 } 1360 | struct_declarator_list COMMA struct_declarator { 1361 $$->push_back($3); 1362 } 1363 ; 1364 1365 struct_declarator 1366 : IDENTIFIER { 1367 if (context->reservedErrorCheck(@1, *$1.string)) 1368 context->recover(); 1369 1370 TType* type = new TType(EbtVoid, EbpUndefined); 1371 $$ = new TField(type, $1.string, @1); 1372 } 1373 | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { 1374 if (context->reservedErrorCheck(@1, *$1.string)) 1375 context->recover(); 1376 1377 TType* type = new TType(EbtVoid, EbpUndefined); 1378 int size; 1379 if (context->arraySizeErrorCheck($3->getLine(), $3, size)) 1380 context->recover(); 1381 type->setArraySize(size); 1382 1383 $$ = new TField(type, $1.string, @1); 1384 } 1385 ; 1386 1387 initializer 1388 : assignment_expression { $$ = $1; } 1389 ; 1390 1391 declaration_statement 1392 : declaration { $$ = $1; } 1393 ; 1394 1395 statement 1396 : compound_statement { $$ = $1; } 1397 | simple_statement { $$ = $1; } 1398 ; 1399 1400 // Grammar Note: Labeled statements for SWITCH only; 'goto' is not supported. 1401 1402 simple_statement 1403 : declaration_statement { $$ = $1; } 1404 | expression_statement { $$ = $1; } 1405 | selection_statement { $$ = $1; } 1406 | switch_statement { $$ = $1; } 1407 | case_label { $$ = $1; } 1408 | iteration_statement { $$ = $1; } 1409 | jump_statement { $$ = $1; } 1410 ; 1411 1412 compound_statement 1413 : LEFT_BRACE RIGHT_BRACE { $$ = 0; } 1414 | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { 1415 if ($3 != 0) { 1416 $3->setOp(EOpSequence); 1417 $3->setEndLine(@5); 1418 } 1419 $$ = $3; 1420 } 1421 ; 1422 1423 statement_no_new_scope 1424 : compound_statement_no_new_scope { $$ = $1; } 1425 | simple_statement { $$ = $1; } 1426 ; 1427 1428 statement_with_scope 1429 : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; } 1430 | { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; } 1431 ; 1432 1433 compound_statement_no_new_scope 1434 // Statement that doesn't create a new scope, for selection_statement, iteration_statement 1435 : LEFT_BRACE RIGHT_BRACE { 1436 $$ = 0; 1437 } 1438 | LEFT_BRACE statement_list RIGHT_BRACE { 1439 if ($2) { 1440 $2->setOp(EOpSequence); 1441 $2->setEndLine(@3); 1442 } 1443 $$ = $2; 1444 } 1445 ; 1446 1447 statement_list 1448 : statement { 1449 $$ = context->intermediate.makeAggregate($1, @$); 1450 } 1451 | statement_list statement { 1452 $$ = context->intermediate.growAggregate($1, $2, @$); 1453 } 1454 ; 1455 1456 expression_statement 1457 : SEMICOLON { $$ = 0; } 1458 | expression SEMICOLON { $$ = static_cast<TIntermNode*>($1); } 1459 ; 1460 1461 selection_statement 1462 : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { 1463 if (context->boolErrorCheck(@1, $3)) 1464 context->recover(); 1465 $$ = context->intermediate.addSelection($3, $5, @1); 1466 } 1467 ; 1468 1469 selection_rest_statement 1470 : statement_with_scope ELSE statement_with_scope { 1471 $$.node1 = $1; 1472 $$.node2 = $3; 1473 } 1474 | statement_with_scope { 1475 $$.node1 = $1; 1476 $$.node2 = 0; 1477 } 1478 ; 1479 1480 switch_statement 1481 : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement { 1482 $$ = context->addSwitch($3, $6, @1); 1483 context->decrSwitchNestingLevel(); 1484 } 1485 ; 1486 1487 case_label 1488 : CASE constant_expression COLON { 1489 $$ = context->addCase($2, @1); 1490 } 1491 | DEFAULT COLON { 1492 $$ = context->addDefault(@1); 1493 } 1494 ; 1495 1496 condition 1497 // In 1996 c++ draft, conditions can include single declarations 1498 : expression { 1499 $$ = $1; 1500 if (context->boolErrorCheck($1->getLine(), $1)) 1501 context->recover(); 1502 } 1503 | fully_specified_type IDENTIFIER EQUAL initializer { 1504 TIntermNode *intermNode; 1505 if (context->boolErrorCheck(@2, $1)) 1506 context->recover(); 1507 1508 if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode)) 1509 $$ = $4; 1510 else { 1511 context->recover(); 1512 $$ = 0; 1513 } 1514 } 1515 ; 1516 1517 iteration_statement 1518 : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } condition RIGHT_PAREN statement_no_new_scope { 1519 context->symbolTable.pop(); 1520 $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1); 1521 context->decrLoopNestingLevel(); 1522 } 1523 | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { 1524 if (context->boolErrorCheck(@8, $6)) 1525 context->recover(); 1526 1527 $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); 1528 context->decrLoopNestingLevel(); 1529 } 1530 | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { 1531 context->symbolTable.pop(); 1532 $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1); 1533 context->decrLoopNestingLevel(); 1534 } 1535 ; 1536 1537 for_init_statement 1538 : expression_statement { 1539 $$ = $1; 1540 } 1541 | declaration_statement { 1542 $$ = $1; 1543 } 1544 ; 1545 1546 conditionopt 1547 : condition { 1548 $$ = $1; 1549 } 1550 | /* May be null */ { 1551 $$ = 0; 1552 } 1553 ; 1554 1555 for_rest_statement 1556 : conditionopt SEMICOLON { 1557 $$.node1 = $1; 1558 $$.node2 = 0; 1559 } 1560 | conditionopt SEMICOLON expression { 1561 $$.node1 = $1; 1562 $$.node2 = $3; 1563 } 1564 ; 1565 1566 jump_statement 1567 : CONTINUE SEMICOLON { 1568 $$ = context->addBranch(EOpContinue, @1); 1569 } 1570 | BREAK SEMICOLON { 1571 $$ = context->addBranch(EOpBreak, @1); 1572 } 1573 | RETURN SEMICOLON { 1574 $$ = context->addBranch(EOpReturn, @1); 1575 } 1576 | RETURN expression SEMICOLON { 1577 $$ = context->addBranch(EOpReturn, $2, @1); 1578 } 1579 | DISCARD SEMICOLON { 1580 FRAG_ONLY("discard", @1); 1581 $$ = context->addBranch(EOpKill, @1); 1582 } 1583 ; 1584 1585 // Grammar Note: No 'goto'. Gotos are not supported. 1586 1587 translation_unit 1588 : external_declaration { 1589 $$ = $1; 1590 context->setTreeRoot($$); 1591 } 1592 | translation_unit external_declaration { 1593 $$ = context->intermediate.growAggregate($1, $2, @$); 1594 context->setTreeRoot($$); 1595 } 1596 ; 1597 1598 external_declaration 1599 : function_definition { 1600 $$ = $1; 1601 } 1602 | declaration { 1603 $$ = $1; 1604 } 1605 ; 1606 1607 function_definition 1608 : function_prototype { 1609 context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate); 1610 } 1611 compound_statement_no_new_scope { 1612 $$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1); 1613 } 1614 ; 1615 1616 %% 1617 1618 int glslang_parse(TParseContext* context) { 1619 return yyparse(context, context->getScanner()); 1620 } 1621