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 Lex specification for GLSL ES. 17 Based on ANSI C grammar, Lex specification: 18 http://www.lysator.liu.se/c/ANSI-C-grammar-l.html 19 20 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, 21 WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). 22 */ 23 24 %top{ 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 54 %{ 55 #include "glslang.h" 56 #include "ParseHelper.h" 57 #include "preprocessor/Token.h" 58 #include "util.h" 59 #include "glslang_tab.h" 60 61 /* windows only pragma */ 62 #ifdef _MSC_VER 63 #pragma warning(disable : 4102) 64 #endif 65 66 #define YY_USER_ACTION \ 67 yylloc->first_file = yylloc->last_file = yycolumn; \ 68 yylloc->first_line = yylloc->last_line = yylineno; 69 70 #define YY_INPUT(buf, result, max_size) \ 71 result = string_input(buf, max_size, yyscanner); 72 73 static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner); 74 static int check_type(yyscan_t yyscanner); 75 static int reserved_word(yyscan_t yyscanner); 76 static int ES2_reserved_ES3_keyword(TParseContext *context, int token); 77 static int ES2_keyword_ES3_reserved(TParseContext *context, int token); 78 static int ES2_identifier_ES3_keyword(TParseContext *context, int token); 79 static int uint_constant(TParseContext *context); 80 static int int_constant(yyscan_t yyscanner); 81 static int float_constant(yyscan_t yyscanner); 82 static int floatsuffix_check(TParseContext* context); 83 %} 84 85 %option noyywrap nounput never-interactive 86 %option yylineno reentrant bison-bridge bison-locations 87 %option extra-type="TParseContext*" 88 %x COMMENT FIELDS 89 90 D [0-9] 91 L [a-zA-Z_] 92 H [a-fA-F0-9] 93 E [Ee][+-]?{D}+ 94 O [0-7] 95 96 %% 97 98 %{ 99 TParseContext* context = yyextra; 100 %} 101 102 "invariant" { return(INVARIANT); } 103 "highp" { return(HIGH_PRECISION); } 104 "mediump" { return(MEDIUM_PRECISION); } 105 "lowp" { return(LOW_PRECISION); } 106 "precision" { return(PRECISION); } 107 108 "attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); } 109 "const" { return(CONST_QUAL); } 110 "uniform" { return(UNIFORM); } 111 "varying" { return ES2_keyword_ES3_reserved(context, VARYING); } 112 113 "break" { return(BREAK); } 114 "continue" { return(CONTINUE); } 115 "do" { return(DO); } 116 "for" { return(FOR); } 117 "while" { return(WHILE); } 118 119 "if" { return(IF); } 120 "else" { return(ELSE); } 121 "switch" { return ES2_reserved_ES3_keyword(context, SWITCH); } 122 "case" { return ES2_reserved_ES3_keyword(context, CASE); } 123 "default" { return ES2_reserved_ES3_keyword(context, DEFAULT); } 124 125 "centroid" { return ES2_reserved_ES3_keyword(context, CENTROID); } 126 "flat" { return ES2_reserved_ES3_keyword(context, FLAT); } 127 "smooth" { return ES2_reserved_ES3_keyword(context, SMOOTH); } 128 129 "in" { return(IN_QUAL); } 130 "out" { return(OUT_QUAL); } 131 "inout" { return(INOUT_QUAL); } 132 133 "float" { context->lexAfterType = true; return(FLOAT_TYPE); } 134 "int" { context->lexAfterType = true; return(INT_TYPE); } 135 "uint" { return ES2_identifier_ES3_keyword(context, UINT_TYPE); } 136 "void" { context->lexAfterType = true; return(VOID_TYPE); } 137 "bool" { context->lexAfterType = true; return(BOOL_TYPE); } 138 "true" { yylval->lex.b = true; return(BOOLCONSTANT); } 139 "false" { yylval->lex.b = false; return(BOOLCONSTANT); } 140 141 "discard" { return(DISCARD); } 142 "return" { return(RETURN); } 143 144 "mat2" { context->lexAfterType = true; return(MATRIX2); } 145 "mat3" { context->lexAfterType = true; return(MATRIX3); } 146 "mat4" { context->lexAfterType = true; return(MATRIX4); } 147 148 "mat2x2" { return ES2_identifier_ES3_keyword(context, MATRIX2); } 149 "mat3x3" { return ES2_identifier_ES3_keyword(context, MATRIX3); } 150 "mat4x4" { return ES2_identifier_ES3_keyword(context, MATRIX4); } 151 152 "mat2x3" { return ES2_identifier_ES3_keyword(context, MATRIX2x3); } 153 "mat3x2" { return ES2_identifier_ES3_keyword(context, MATRIX3x2); } 154 "mat2x4" { return ES2_identifier_ES3_keyword(context, MATRIX2x4); } 155 "mat4x2" { return ES2_identifier_ES3_keyword(context, MATRIX4x2); } 156 "mat3x4" { return ES2_identifier_ES3_keyword(context, MATRIX3x4); } 157 "mat4x3" { return ES2_identifier_ES3_keyword(context, MATRIX4x3); } 158 159 "vec2" { context->lexAfterType = true; return (VEC2); } 160 "vec3" { context->lexAfterType = true; return (VEC3); } 161 "vec4" { context->lexAfterType = true; return (VEC4); } 162 "ivec2" { context->lexAfterType = true; return (IVEC2); } 163 "ivec3" { context->lexAfterType = true; return (IVEC3); } 164 "ivec4" { context->lexAfterType = true; return (IVEC4); } 165 "uvec2" { return ES2_identifier_ES3_keyword(context, UVEC2); } 166 "uvec3" { return ES2_identifier_ES3_keyword(context, UVEC3); } 167 "uvec4" { return ES2_identifier_ES3_keyword(context, UVEC4); } 168 "bvec2" { context->lexAfterType = true; return (BVEC2); } 169 "bvec3" { context->lexAfterType = true; return (BVEC3); } 170 "bvec4" { context->lexAfterType = true; return (BVEC4); } 171 172 "sampler2D" { context->lexAfterType = true; return SAMPLER2D; } 173 "samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; } 174 "sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; } 175 "samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; } 176 "sampler3D" { context->lexAfterType = true; return SAMPLER3D; } 177 "sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); } 178 "sampler2DArray" { return ES2_identifier_ES3_keyword(context, SAMPLER2DARRAY); } 179 "isampler2D" { return ES2_identifier_ES3_keyword(context, ISAMPLER2D); } 180 "isampler3D" { return ES2_identifier_ES3_keyword(context, ISAMPLER3D); } 181 "isamplerCube" { return ES2_identifier_ES3_keyword(context, ISAMPLERCUBE); } 182 "isampler2DArray" { return ES2_identifier_ES3_keyword(context, ISAMPLER2DARRAY); } 183 "usampler2D" { return ES2_identifier_ES3_keyword(context, USAMPLER2D); } 184 "usampler3D" { return ES2_identifier_ES3_keyword(context, USAMPLER3D); } 185 "usamplerCube" { return ES2_identifier_ES3_keyword(context, USAMPLERCUBE); } 186 "usampler2DArray" { return ES2_identifier_ES3_keyword(context, USAMPLER2DARRAY); } 187 "sampler2DShadow" { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); } 188 "samplerCubeShadow" { return ES2_identifier_ES3_keyword(context, SAMPLERCUBESHADOW); } 189 "sampler2DArrayShadow" { return ES2_identifier_ES3_keyword(context, SAMPLER2DARRAYSHADOW); } 190 191 "struct" { context->lexAfterType = true; return(STRUCT); } 192 193 "layout" { return ES2_identifier_ES3_keyword(context, LAYOUT); } 194 195 /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */ 196 "coherent" | 197 "restrict" | 198 "readonly" | 199 "writeonly" | 200 "resource" | 201 "atomic_uint" | 202 "noperspective" | 203 "patch" | 204 "sample" | 205 "subroutine" | 206 "common" | 207 "partition" | 208 "active" | 209 210 "filter" | 211 "image1D" | 212 "image2D" | 213 "image3D" | 214 "imageCube" | 215 "iimage1D" | 216 "iimage2D" | 217 "iimage3D" | 218 "iimageCube" | 219 "uimage1D" | 220 "uimage2D" | 221 "uimage3D" | 222 "uimageCube" | 223 "image1DArray" | 224 "image2DArray" | 225 "iimage1DArray" | 226 "iimage2DArray" | 227 "uimage1DArray" | 228 "uimage2DArray" | 229 "image1DShadow" | 230 "image2DShadow" | 231 "image1DArrayShadow" | 232 "image2DArrayShadow" | 233 "imageBuffer" | 234 "iimageBuffer" | 235 "uimageBuffer" | 236 237 "sampler1DArray" | 238 "sampler1DArrayShadow" | 239 "isampler1D" | 240 "isampler1DArray" | 241 "usampler1D" | 242 "usampler1DArray" | 243 "isampler2DRect" | 244 "usampler2DRect" | 245 "samplerBuffer" | 246 "isamplerBuffer" | 247 "usamplerBuffer" | 248 "sampler2DMS" | 249 "isampler2DMS" | 250 "usampler2DMS" | 251 "sampler2DMSArray" | 252 "isampler2DMSArray" | 253 "usampler2DMSArray" { 254 if (context->getShaderVersion() < 300) { 255 yylval->lex.string = NewPoolTString(yytext); 256 return check_type(yyscanner); 257 } 258 return reserved_word(yyscanner); 259 } 260 261 /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */ 262 "packed" { 263 if (context->getShaderVersion() >= 300) 264 { 265 yylval->lex.string = NewPoolTString(yytext); 266 return check_type(yyscanner); 267 } 268 269 return reserved_word(yyscanner); 270 } 271 272 /* Reserved keywords */ 273 "asm" | 274 275 "class" | 276 "union" | 277 "enum" | 278 "typedef" | 279 "template" | 280 "this" | 281 282 "goto" | 283 284 "inline" | 285 "noinline" | 286 "volatile" | 287 "public" | 288 "static" | 289 "extern" | 290 "external" | 291 "interface" | 292 293 "long" | 294 "short" | 295 "double" | 296 "half" | 297 "fixed" | 298 "unsigned" | 299 "superp" | 300 301 "input" | 302 "output" | 303 304 "hvec2" | 305 "hvec3" | 306 "hvec4" | 307 "dvec2" | 308 "dvec3" | 309 "dvec4" | 310 "fvec2" | 311 "fvec3" | 312 "fvec4" | 313 314 "sampler1D" | 315 "sampler1DShadow" | 316 "sampler2DRectShadow" | 317 318 "sizeof" | 319 "cast" | 320 321 "namespace" | 322 "using" { return reserved_word(yyscanner); } 323 324 {L}({L}|{D})* { 325 yylval->lex.string = NewPoolTString(yytext); 326 return check_type(yyscanner); 327 } 328 329 0[xX]{H}+ { return int_constant(yyscanner); } 330 0{O}+ { return int_constant(yyscanner); } 331 {D}+ { return int_constant(yyscanner); } 332 333 0[xX]{H}+[uU] { return uint_constant(context); } 334 0{O}+[uU] { return uint_constant(context); } 335 {D}+[uU] { return uint_constant(context); } 336 337 {D}+{E} { return float_constant(yyscanner); } 338 {D}+"."{D}*({E})? { return float_constant(yyscanner); } 339 "."{D}+({E})? { return float_constant(yyscanner); } 340 341 {D}+{E}[fF] { return floatsuffix_check(context); } 342 {D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); } 343 "."{D}+({E})?[fF] { return floatsuffix_check(context); } 344 345 "+=" { return(ADD_ASSIGN); } 346 "-=" { return(SUB_ASSIGN); } 347 "*=" { return(MUL_ASSIGN); } 348 "/=" { return(DIV_ASSIGN); } 349 "%=" { return(MOD_ASSIGN); } 350 "<<=" { return(LEFT_ASSIGN); } 351 ">>=" { return(RIGHT_ASSIGN); } 352 "&=" { return(AND_ASSIGN); } 353 "^=" { return(XOR_ASSIGN); } 354 "|=" { return(OR_ASSIGN); } 355 356 "++" { return(INC_OP); } 357 "--" { return(DEC_OP); } 358 "&&" { return(AND_OP); } 359 "||" { return(OR_OP); } 360 "^^" { return(XOR_OP); } 361 "<=" { return(LE_OP); } 362 ">=" { return(GE_OP); } 363 "==" { return(EQ_OP); } 364 "!=" { return(NE_OP); } 365 "<<" { return(LEFT_OP); } 366 ">>" { return(RIGHT_OP); } 367 ";" { context->lexAfterType = false; return(SEMICOLON); } 368 ("{"|"<%") { context->lexAfterType = false; return(LEFT_BRACE); } 369 ("}"|"%>") { return(RIGHT_BRACE); } 370 "," { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); } 371 ":" { return(COLON); } 372 "=" { context->lexAfterType = false; return(EQUAL); } 373 "(" { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); } 374 ")" { context->inTypeParen = false; return(RIGHT_PAREN); } 375 ("["|"<:") { return(LEFT_BRACKET); } 376 ("]"|":>") { return(RIGHT_BRACKET); } 377 "." { BEGIN(FIELDS); return(DOT); } 378 "!" { return(BANG); } 379 "-" { return(DASH); } 380 "~" { return(TILDE); } 381 "+" { return(PLUS); } 382 "*" { return(STAR); } 383 "/" { return(SLASH); } 384 "%" { return(PERCENT); } 385 "<" { return(LEFT_ANGLE); } 386 ">" { return(RIGHT_ANGLE); } 387 "|" { return(VERTICAL_BAR); } 388 "^" { return(CARET); } 389 "&" { return(AMPERSAND); } 390 "?" { return(QUESTION); } 391 392 <FIELDS>{L}({L}|{D})* { 393 BEGIN(INITIAL); 394 yylval->lex.string = NewPoolTString(yytext); 395 return FIELD_SELECTION; 396 } 397 <FIELDS>[ \t\v\f\r] {} 398 399 [ \t\v\n\f\r] { } 400 <*><<EOF>> { context->AfterEOF = true; yyterminate(); } 401 <*>. { context->warning(*yylloc, "Unknown char", yytext, ""); return 0; } 402 403 %% 404 405 yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { 406 pp::Token token; 407 yyget_extra(yyscanner)->getPreprocessor().lex(&token); 408 yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); 409 if (len < max_size) 410 memcpy(buf, token.text.c_str(), len); 411 yyset_column(token.location.file, yyscanner); 412 yyset_lineno(token.location.line, yyscanner); 413 414 if (len >= max_size) 415 YY_FATAL_ERROR("Input buffer overflow"); 416 else if (len > 0) 417 buf[len++] = ' '; 418 return len; 419 } 420 421 int check_type(yyscan_t yyscanner) { 422 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; 423 424 int token = IDENTIFIER; 425 TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion()); 426 if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) { 427 TVariable* variable = static_cast<TVariable*>(symbol); 428 if (variable->isUserType()) { 429 yyextra->lexAfterType = true; 430 token = TYPE_NAME; 431 } 432 } 433 yylval->lex.symbol = symbol; 434 return token; 435 } 436 437 int reserved_word(yyscan_t yyscanner) { 438 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; 439 440 yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); 441 yyextra->recover(); 442 return 0; 443 } 444 445 int ES2_reserved_ES3_keyword(TParseContext *context, int token) 446 { 447 yyscan_t yyscanner = (yyscan_t) context->getScanner(); 448 449 if (context->getShaderVersion() < 300) 450 { 451 return reserved_word(yyscanner); 452 } 453 454 return token; 455 } 456 457 int ES2_keyword_ES3_reserved(TParseContext *context, int token) 458 { 459 yyscan_t yyscanner = (yyscan_t) context->getScanner(); 460 461 if (context->getShaderVersion() >= 300) 462 { 463 return reserved_word(yyscanner); 464 } 465 466 return token; 467 } 468 469 int ES2_identifier_ES3_keyword(TParseContext *context, int token) 470 { 471 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); 472 yyscan_t yyscanner = (yyscan_t) context->getScanner(); 473 474 // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name 475 if (context->getShaderVersion() < 300) 476 { 477 yylval->lex.string = NewPoolTString(yytext); 478 return check_type(yyscanner); 479 } 480 481 return token; 482 } 483 484 int uint_constant(TParseContext *context) 485 { 486 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); 487 488 if (context->getShaderVersion() < 300) 489 { 490 context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); 491 context->recover(); 492 return 0; 493 } 494 495 if (!atou_clamp(yytext, &(yylval->lex.u))) 496 yyextra->warning(*yylloc, "Integer overflow", yytext, ""); 497 498 return UINTCONSTANT; 499 } 500 501 int floatsuffix_check(TParseContext* context) 502 { 503 struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); 504 505 if (context->getShaderVersion() < 300) 506 { 507 context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); 508 context->recover(); 509 return 0; 510 } 511 512 if (!atof_clamp(yytext, &(yylval->lex.f))) 513 yyextra->warning(*yylloc, "Float overflow", yytext, ""); 514 515 return(FLOATCONSTANT); 516 } 517 518 int int_constant(yyscan_t yyscanner) { 519 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; 520 521 if (!atoi_clamp(yytext, &(yylval->lex.i))) 522 yyextra->warning(*yylloc, "Integer overflow", yytext, ""); 523 return INTCONSTANT; 524 } 525 526 int float_constant(yyscan_t yyscanner) { 527 struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; 528 529 if (!atof_clamp(yytext, &(yylval->lex.f))) 530 yyextra->warning(*yylloc, "Float overflow", yytext, ""); 531 return FLOATCONSTANT; 532 } 533 534 void yyerror(YYLTYPE* lloc, TParseContext* context, void* scanner, const char* reason) { 535 struct yyguts_t* yyg = (struct yyguts_t*) scanner; 536 537 if (context->AfterEOF) { 538 context->error(*lloc, reason, "unexpected EOF"); 539 } else { 540 context->error(*lloc, reason, yytext); 541 } 542 context->recover(); 543 } 544 545 int glslang_initialize(TParseContext* context) { 546 yyscan_t scanner = NULL; 547 if (yylex_init_extra(context, &scanner)) 548 return 1; 549 550 context->setScanner(scanner); 551 return 0; 552 } 553 554 int glslang_finalize(TParseContext* context) { 555 yyscan_t scanner = context->getScanner(); 556 if (scanner == NULL) return 0; 557 558 context->setScanner(NULL); 559 yylex_destroy(scanner); 560 561 return 0; 562 } 563 564 int glslang_scan(size_t count, const char* const string[], const int length[], 565 TParseContext* context) { 566 yyrestart(NULL, context->getScanner()); 567 yyset_column(0, context->getScanner()); 568 yyset_lineno(1, context->getScanner()); 569 context->AfterEOF = false; 570 571 // Initialize preprocessor. 572 if (!context->getPreprocessor().init(count, string, length)) 573 return 1; 574 575 // Define extension macros. 576 const TExtensionBehavior& extBehavior = context->extensionBehavior(); 577 for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); 578 iter != extBehavior.end(); ++iter) 579 { 580 context->getPreprocessor().predefineMacro(iter->first.c_str(), 1); 581 } 582 583 context->getPreprocessor().predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); 584 585 return 0; 586 } 587 588