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