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 8This file contains the Lex specification for GLSL ES. 9Based on ANSI C grammar, Lex specification: 10http://www.lysator.liu.se/c/ANSI-C-grammar-l.html 11 12IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, 13WHICH 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 58static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner); 59static int check_type(yyscan_t yyscanner); 60static int reserved_word(yyscan_t yyscanner); 61static int ES2_reserved_ES3_keyword(TParseContext *context, int token); 62static int ES2_keyword_ES3_reserved(TParseContext *context, int token); 63static int ES2_ident_ES3_keyword(TParseContext *context, int token); 64static int uint_constant(TParseContext *context); 65static int int_constant(yyscan_t yyscanner); 66static int float_constant(yyscan_t yyscanner); 67static 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 74D [0-9] 75L [a-zA-Z_] 76H [a-fA-F0-9] 77E [Ee][+-]?{D}+ 78O [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 3130[xX]{H}+ { return int_constant(yyscanner); } 3140{O}+ { return int_constant(yyscanner); } 315{D}+ { return int_constant(yyscanner); } 316 3170[xX]{H}+[uU] { return uint_constant(context); } 3180{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 382yy_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 398int 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 413int 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 421int 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 433int 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 445int 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 460int 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 478int 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 495void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) { 496 context->error(*lloc, reason, yyget_text(context->scanner)); 497 context->recover(); 498} 499 500int 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 508int 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 516int 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 525int 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 535int 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