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