/* // // Copyright 2002 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This file contains the Lex specification for GLSL ES. Based on ANSI C grammar, Lex specification: http://www.lysator.liu.se/c/ANSI-C-grammar-l.html IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py WHICH GENERATES THE GLSL ES LEXER (glslang_lex_autogen.cpp). */ %top{ // GENERATED FILE - DO NOT EDIT. // Generated by generate_parser.py from glslang.l // // Copyright 2019 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // glslang.l: // Lexer for the OpenGL shading language. // Ignore errors in auto-generated code. #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wswitch-enum" #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-variable" #elif defined(_MSC_VER) #pragma warning(disable: 4005) #pragma warning(disable: 4065) #pragma warning(disable: 4189) #pragma warning(disable: 4244) #pragma warning(disable: 4505) #pragma warning(disable: 4701) #pragma warning(disable: 4702) #endif #if defined(__clang__) #pragma clang diagnostic ignored "-Wimplicit-fallthrough" #if defined(__APPLE__) // Older clang versions don't have -Wextra-semi-stmt, and detecting Apple clang versions is // difficult because they use different yet overlapping version numbers vs. regular clang. #pragma clang diagnostic ignored "-Wunknown-warning-option" #endif // Flex isn't semi-colon clean. #pragma clang diagnostic ignored "-Wextra-semi-stmt" #pragma clang diagnostic ignored "-Wunreachable-code" #endif } %{ #include "compiler/translator/glslang.h" #include "compiler/translator/ParseContext.h" #include "compiler/preprocessor/Token.h" #include "compiler/translator/util.h" #include "compiler/translator/length_limits.h" using namespace sh; #include "glslang_tab_autogen.h" /* windows only pragma */ #ifdef _MSC_VER #pragma warning(disable : 4102) #endif // Workaround for flex using the register keyword, deprecated in C++11. #ifdef __cplusplus #if __cplusplus > 199711L #define register #endif #endif #define YY_NO_INPUT #define YY_USER_ACTION \ yylloc->first_file = yylloc->last_file = yycolumn; \ yylloc->first_line = yylloc->last_line = yylineno; #define YY_INPUT(buf, result, max_size) \ result = string_input(buf, max_size, yyscanner); static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner); static int check_type(yyscan_t yyscanner); static int reserved_word(yyscan_t yyscanner); // Tests if an extension is enabled. If the extension is promoted to core, this function returns true. static bool is_extension_enabled_or_is_core(TParseContext *context, int extension_version, TExtension extension, int promotion_version); // Helpers to determine if a symbol is reserved, keyword in extension or core, or identifier. // Formatted as: // // [V1_reserved_][V2_extension_][V3_keyword] // // which means in version V1, the symbol is reserved, and remains reserved until V3. From versions // V2 until V3, it's a keyword if the extension is enabled. From version V3 on, it's a keyword in // the spec itself. Prior to V1, the symbol can be used as identifier. static int ES2_extension_2_ES3_keyword(TParseContext *context, TExtension extension1, TExtension extension2, int token); static int ES2_reserved_ES3_keyword(TParseContext *context, int token); static int ES2_keyword_ES3_reserved(TParseContext *context, int token); static int ES3_keyword(TParseContext *context, int token); static int ES3_reserved_ES3_1_keyword(TParseContext *context, int token); static int ES2_reserved_ES3_1_keyword(TParseContext *context, int token); static int ES3_1_keyword(TParseContext *context, int token); static int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token); static int ES3_extension(TParseContext *context, TExtension extension, int token); static int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token); static int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token); static int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token); static int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token); static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token); static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2); static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2); static int WEBGL_video_texture_extension(TParseContext *context, int token); static int uint_constant(TParseContext *context); static int int_constant(TParseContext *context); static int float_constant(yyscan_t yyscanner); static int floatsuffix_check(TParseContext* context); static int yuvcscstandardext_constant(TParseContext *context); %} %option noyywrap nounput never-interactive %option yylineno reentrant bison-bridge bison-locations %option extra-type="TParseContext*" %x FIELDS D [0-9] L [a-zA-Z_] H [a-fA-F0-9] E [Ee][+-]?{D}+ O [0-7] %% %{ TParseContext* context = yyextra; %} "invariant" { return INVARIANT; } "highp" { return HIGH_PRECISION; } "mediump" { return MEDIUM_PRECISION; } "lowp" { return LOW_PRECISION; } "precision" { return PRECISION; } "attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); } "const" { return CONST_QUAL; } "uniform" { return UNIFORM; } "buffer" { return ES3_1_keyword(context, BUFFER); } "varying" { return ES2_keyword_ES3_reserved(context, VARYING); } "break" { return BREAK; } "continue" { return CONTINUE; } "do" { return DO; } "for" { return FOR; } "while" { return WHILE; } "if" { return IF; } "else" { return ELSE; } "switch" { return ES2_reserved_ES3_keyword(context, SWITCH); } "case" { return ES3_keyword(context, CASE); } "default" { return ES2_reserved_ES3_keyword(context, DEFAULT); } "centroid" { return ES3_keyword(context, CENTROID); } "flat" { return ES2_reserved_ES3_keyword(context, FLAT); } "smooth" { return ES3_keyword(context, SMOOTH); } "noperspective" { return ES3_reserved_ES3_extension(context, TExtension::NV_shader_noperspective_interpolation, NOPERSPECTIVE); } "patch" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::EXT_tessellation_shader, PATCH); } "in" { return IN_QUAL; } "out" { return OUT_QUAL; } "inout" { return INOUT_QUAL; } "shared" { return ES3_1_keyword(context, SHARED); } "float" { return FLOAT_TYPE; } "int" { return INT_TYPE; } "uint" { return ES3_keyword(context, UINT_TYPE); } "void" { return VOID_TYPE; } "bool" { return BOOL_TYPE; } "true" { yylval->lex.b = true; return BOOLCONSTANT; } "false" { yylval->lex.b = false; return BOOLCONSTANT; } "discard" { return DISCARD; } "return" { return RETURN; } "mat2" { return MATRIX2; } "mat3" { return MATRIX3; } "mat4" { return MATRIX4; } "mat2x2" { return ES3_keyword(context, MATRIX2); } "mat3x3" { return ES3_keyword(context, MATRIX3); } "mat4x4" { return ES3_keyword(context, MATRIX4); } "mat2x3" { return ES3_keyword(context, MATRIX2x3); } "mat3x2" { return ES3_keyword(context, MATRIX3x2); } "mat2x4" { return ES3_keyword(context, MATRIX2x4); } "mat4x2" { return ES3_keyword(context, MATRIX4x2); } "mat3x4" { return ES3_keyword(context, MATRIX3x4); } "mat4x3" { return ES3_keyword(context, MATRIX4x3); } "vec2" { return VEC2; } "vec3" { return VEC3; } "vec4" { return VEC4; } "ivec2" { return IVEC2; } "ivec3" { return IVEC3; } "ivec4" { return IVEC4; } "bvec2" { return BVEC2; } "bvec3" { return BVEC3; } "bvec4" { return BVEC4; } "uvec2" { return ES3_keyword(context, UVEC2); } "uvec3" { return ES3_keyword(context, UVEC3); } "uvec4" { return ES3_keyword(context, UVEC4); } "sampler2D" { return SAMPLER2D; } "samplerCube" { return SAMPLERCUBE; } "samplerExternalOES" { return SAMPLER_EXTERNAL_OES; } "sampler3D" { return ES2_reserved_ES2_extension_ES3_keyword(context, TExtension::OES_texture_3D, SAMPLER3D); } "sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); } "sampler2DRect" { return SAMPLER2DRECT; } "sampler2DArray" { return ES3_keyword(context, SAMPLER2DARRAY); } "sampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, SAMPLER2DMS); } "isampler2D" { return ES3_keyword(context, ISAMPLER2D); } "isampler3D" { return ES3_keyword(context, ISAMPLER3D); } "isamplerCube" { return ES3_keyword(context, ISAMPLERCUBE); } "isampler2DArray" { return ES3_keyword(context, ISAMPLER2DARRAY); } "isampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, ISAMPLER2DMS); } "usampler2D" { return ES3_keyword(context, USAMPLER2D); } "usampler3D" { return ES3_keyword(context, USAMPLER3D); } "usamplerCube" { return ES3_keyword(context, USAMPLERCUBE); } "usampler2DArray" { return ES3_keyword(context, USAMPLER2DARRAY); } "usampler2DMS" { return ES3_reserved_ES3_extension_ES3_1_keyword(context, TExtension::ANGLE_texture_multisample, USAMPLER2DMS); } "sampler2DShadow" { return ES2_reserved_ES2_extension_ES3_keyword(context, TExtension::EXT_shadow_samplers, SAMPLER2DSHADOW); } "samplerCubeShadow" { return ES3_keyword(context, SAMPLERCUBESHADOW); } "sampler2DArrayShadow" { return ES3_keyword(context, SAMPLER2DARRAYSHADOW); } "__samplerExternal2DY2YEXT" { return ES3_extension(context, TExtension::EXT_YUV_target, SAMPLEREXTERNAL2DY2YEXT); } "sampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, SAMPLER2DMSARRAY); } "isampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, ISAMPLER2DMSARRAY); } "usampler2DMSArray" { return ES3_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, USAMPLER2DMSARRAY); } "samplerCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYOES, SAMPLERCUBEARRAYEXT); } "samplerBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, SAMPLERBUFFER, SAMPLERBUFFER); } "samplerCubeArrayShadow" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYSHADOWOES, SAMPLERCUBEARRAYSHADOWEXT); } "isamplerCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, ISAMPLERCUBEARRAYOES, ISAMPLERCUBEARRAYEXT); } "isamplerBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, ISAMPLERBUFFER, ISAMPLERBUFFER); } "usamplerCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, USAMPLERCUBEARRAYOES, USAMPLERCUBEARRAYEXT); } "usamplerBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, USAMPLERBUFFER, USAMPLERBUFFER); } "samplerVideoWEBGL" { return WEBGL_video_texture_extension(context, SAMPLERVIDEOWEBGL); } "struct" { return STRUCT; } "layout" { return ES2_extension_2_ES3_keyword(context, TExtension::EXT_shader_framebuffer_fetch, TExtension::EXT_shader_framebuffer_fetch_non_coherent, LAYOUT); } "yuvCscStandardEXT" { return ES3_extension(context, TExtension::EXT_YUV_target, YUVCSCSTANDARDEXT); } "itu_601" { return yuvcscstandardext_constant(context); } "itu_601_full_range" { return yuvcscstandardext_constant(context); } "itu_709" { return yuvcscstandardext_constant(context); } "image2D" { return ES3_reserved_ES3_1_keyword(context, IMAGE2D); } "iimage2D" { return ES3_reserved_ES3_1_keyword(context, IIMAGE2D); } "uimage2D" { return ES3_reserved_ES3_1_keyword(context, UIMAGE2D); } "image2DArray" { return ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); } "iimage2DArray" { return ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); } "uimage2DArray" { return ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); } "image3D" { return ES3_reserved_ES3_1_keyword(context, IMAGE3D); } "uimage3D" { return ES3_reserved_ES3_1_keyword(context, UIMAGE3D); } "iimage3D" { return ES3_reserved_ES3_1_keyword(context, IIMAGE3D); } "iimageCube" { return ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); } "uimageCube" { return ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); } "imageCube" { return ES3_reserved_ES3_1_keyword(context, IMAGECUBE); } "imageCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, IMAGECUBEARRAYOES, IMAGECUBEARRAYEXT); } "iimageCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, IIMAGECUBEARRAYOES, IIMAGECUBEARRAYEXT); } "uimageCubeArray" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array, UIMAGECUBEARRAYOES, UIMAGECUBEARRAYEXT); } "imageBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, IMAGEBUFFER, IMAGEBUFFER); } "iimageBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, IIMAGEBUFFER, IIMAGEBUFFER); } "uimageBuffer" { return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer, UIMAGEBUFFER, UIMAGEBUFFER); } "readonly" { return ES3_reserved_ES3_1_keyword(context, READONLY); } "writeonly" { return ES3_reserved_ES3_1_keyword(context, WRITEONLY); } "coherent" { return ES3_reserved_ES3_1_keyword(context, COHERENT); } "restrict" { return ES3_reserved_ES3_1_keyword(context, RESTRICT); } "volatile" { return ES2_reserved_ES3_1_keyword(context, VOLATILE); } "atomic_uint" { return ES3_reserved_ES3_1_keyword(context, ATOMICUINT); } "sample" { return ES3_reserved_ES3_extension_ES3_2_keyword(context, TExtension::OES_shader_multisample_interpolation, SAMPLE); } "precise" { return ES3_1_reserved_ES3_1_extension_ES3_2_keyword(context, TExtension::EXT_gpu_shader5, PRECISE); } /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */ "resource" | "subroutine" | "common" | "partition" | "active" | "filter" | "image1D" | "iimage1D" | "uimage1D" | "image1DArray" | "iimage1DArray" | "uimage1DArray" | "image1DShadow" | "image2DShadow" | "image1DArrayShadow" | "image2DArrayShadow" | "sampler1DArray" | "sampler1DArrayShadow" | "isampler1D" | "isampler1DArray" | "usampler1D" | "usampler1DArray" | "isampler2DRect" | "usampler2DRect" { if (context->getShaderVersion() < 300) { yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } return reserved_word(yyscanner); } /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */ "packed" { if (context->getShaderVersion() >= 300) { yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } return reserved_word(yyscanner); } /* Reserved keywords */ "asm" | "class" | "union" | "enum" | "typedef" | "template" | "this" | "goto" | "inline" | "noinline" | "public" | "static" | "extern" | "external" | "interface" | "long" | "short" | "double" | "half" | "fixed" | "unsigned" | "superp" | "input" | "output" | "hvec2" | "hvec3" | "hvec4" | "dvec2" | "dvec3" | "dvec4" | "fvec2" | "fvec3" | "fvec4" | "sampler1D" | "sampler1DShadow" | "sampler2DRectShadow" | "sizeof" | "cast" | "namespace" | "using" { return reserved_word(yyscanner); } {L}({L}|{D})* { yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } 0[xX]{H}+ { return int_constant(context); } 0{O}+ { return int_constant(context); } {D}+ { return int_constant(context); } 0[xX]{H}+[uU] { return uint_constant(context); } 0{O}+[uU] { return uint_constant(context); } {D}+[uU] { return uint_constant(context); } {D}+{E} { return float_constant(yyscanner); } {D}+"."{D}*({E})? { return float_constant(yyscanner); } "."{D}+({E})? { return float_constant(yyscanner); } {D}+{E}[fF] { return floatsuffix_check(context); } {D}+"."{D}*({E})?[fF] { return floatsuffix_check(context); } "."{D}+({E})?[fF] { return floatsuffix_check(context); } "+=" { return ADD_ASSIGN; } "-=" { return SUB_ASSIGN; } "*=" { return MUL_ASSIGN; } "/=" { return DIV_ASSIGN; } "%=" { return MOD_ASSIGN; } "<<=" { return LEFT_ASSIGN; } ">>=" { return RIGHT_ASSIGN; } "&=" { return AND_ASSIGN; } "^=" { return XOR_ASSIGN; } "|=" { return OR_ASSIGN; } "++" { return INC_OP; } "--" { return DEC_OP; } "&&" { return AND_OP; } "||" { return OR_OP; } "^^" { return XOR_OP; } "<=" { return LE_OP; } ">=" { return GE_OP; } "==" { return EQ_OP; } "!=" { return NE_OP; } "<<" { return LEFT_OP; } ">>" { return RIGHT_OP; } ";" { return SEMICOLON; } ("{"|"<%") { return LEFT_BRACE; } ("}"|"%>") { return RIGHT_BRACE; } "," { return COMMA; } ":" { return COLON; } "=" { return EQUAL; } "(" { return LEFT_PAREN; } ")" { return RIGHT_PAREN; } ("["|"<:") { return LEFT_BRACKET; } ("]"|":>") { return RIGHT_BRACKET; } "." { BEGIN(FIELDS); return DOT; } "!" { return BANG; } "-" { return DASH; } "~" { return TILDE; } "+" { return PLUS; } "*" { return STAR; } "/" { return SLASH; } "%" { return PERCENT; } "<" { return LEFT_ANGLE; } ">" { return RIGHT_ANGLE; } "|" { return VERTICAL_BAR; } "^" { return CARET; } "&" { return AMPERSAND; } "?" { return QUESTION; } {L}({L}|{D})* { BEGIN(INITIAL); yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return FIELD_SELECTION; } [ \t\v\f\r] {} . { yyextra->error(*yylloc, "Illegal character at fieldname start", yytext); return 0; } [ \t\v\n\f\r] { } <*><> { yyterminate(); } <*>. { assert(false); return 0; } %% yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { angle::pp::Token token; yyget_extra(yyscanner)->getPreprocessor().lex(&token); yy_size_t len = token.type == angle::pp::Token::LAST ? 0 : token.text.size(); if (len < max_size) memcpy(buf, token.text.c_str(), len); yyset_column(token.location.file, yyscanner); yyset_lineno(token.location.line, yyscanner); if (len >= max_size) YY_FATAL_ERROR("Input buffer overflow"); else if (len > 0) buf[len++] = ' '; return len; } int check_type(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; int token = IDENTIFIER; // Note that the ImmutableString used here isn't static or pool allocated - but it's fine since yytext is valid for the duration of its use. const TSymbol* symbol = yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion()); if (symbol && symbol->isStruct()) { token = TYPE_NAME; } yylval->lex.symbol = symbol; return token; } int reserved_word(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; yyextra->error(*yylloc, "Illegal use of reserved word", yytext); return 0; } static bool is_extension_enabled_or_is_core(TParseContext *context, int extension_version, TExtension extension, int promotion_version) { int version = context->getShaderVersion(); // If version is at least promotion_version, symbol is definitely keyword. Otherwise it's a // keyword if version is at least extension_version (where the extension was introduced) and // the extension is enabled. return version >= promotion_version || (version >= extension_version && context->isExtensionEnabled(extension)); } int ES2_reserved_ES3_keyword(TParseContext *context, int token) { yyscan_t yyscanner = (yyscan_t) context->getScanner(); if (context->getShaderVersion() < 300) { return reserved_word(yyscanner); } return token; } int ES2_keyword_ES3_reserved(TParseContext *context, int token) { yyscan_t yyscanner = (yyscan_t) context->getScanner(); if (context->getShaderVersion() >= 300) { return reserved_word(yyscanner); } return token; } int ES3_reserved_ES3_1_keyword(TParseContext *context, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); if (context->getShaderVersion() < 300) { yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } else if (context->getShaderVersion() == 300) { return reserved_word(yyscanner); } return token; } int ES3_keyword(TParseContext *context, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name if (context->getShaderVersion() < 300) { yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } return token; } int ES2_reserved_ES3_1_keyword(TParseContext *context, int token) { yyscan_t yyscanner = (yyscan_t) context->getScanner(); if (context->getShaderVersion() < 310) { return reserved_word(yyscanner); } return token; } int ES3_1_keyword(TParseContext *context, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.10. if (context->getShaderVersion() >= 310) { return token; } // Otherwise can be used as an identifier/type name yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int WEBGL_video_texture_extension(TParseContext *context, int token) { // Available with WEBGL_video_texture_extension if (context->isExtensionEnabled(TExtension::WEBGL_video_texture)) { return token; } // Otherwise can be used as an identifier/type name struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int ES2_extension_2_ES3_keyword(TParseContext *context, TExtension extension1, TExtension extension2, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension. if (is_extension_enabled_or_is_core(context, 100, extension1, 300)) { return token; } else if (is_extension_enabled_or_is_core(context, 100, extension2, 300)) { return token; } // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token) { yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension. if (is_extension_enabled_or_is_core(context, 100, extension, 300)) { return token; } // Reserved otherwise. return reserved_word(yyscanner); } int ES3_extension(TParseContext *context, TExtension extension, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // a keyword word in GLSL ES 3.00 with enabled extension. if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension)) { return token; } // Otherwise can be used as an identifier/type name yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // a keyword in GLSL ES 3.10 with enabled extension if (is_extension_enabled_or_is_core(context, 310, extension, 320)) { return token; } // a reserved word in GLSL ES 3.00+ if (context->getShaderVersion() >= 300) { return reserved_word(yyscanner); } // Otherwise can be used as an identifier/type name yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); if(context->getShaderVersion() >= 300) { if (context->isExtensionEnabled(extension)) { return token; } else { return reserved_word(yyscanner); } } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context, TExtension extension, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.10 if (is_extension_enabled_or_is_core(context, 300, extension, 310)) { return token; } if(context->getShaderVersion() == 300) { return reserved_word(yyscanner); } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.20 if (is_extension_enabled_or_is_core(context, 300, extension, 320)) { return token; } if(context->getShaderVersion() == 300 ||context->getShaderVersion() == 310) { return reserved_word(yyscanner); } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context, TExtension extension, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension. if (is_extension_enabled_or_is_core(context, 310, extension, 320)) { return token; } // A reserved word in GLSL ES 3.10 if (context->getShaderVersion() == 310) { return reserved_word(yyscanner); } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension. if (is_extension_enabled_or_is_core(context, 310, extension1, 320)) { return token1; } else if (is_extension_enabled_or_is_core(context, 310, extension2, 320)) { return token2; } // A reserved word in GLSL ES 3.10 if (context->getShaderVersion() == 310) { return reserved_word(yyscanner); } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context, TExtension extension1, TExtension extension2, int token1, int token2) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension. if (is_extension_enabled_or_is_core(context, 310, extension1, 320)) { return token1; } else if (is_extension_enabled_or_is_core(context, 310, extension2, 320)) { return token2; } // A reserved word in GLSL ES 3.00 and 3.10 if (context->getShaderVersion() >= 300) { return reserved_word(yyscanner); } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int uint_constant(TParseContext *context) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); if (context->getShaderVersion() < 300) { context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext); return 0; } if (!atoi_clamp(yytext, &(yylval->lex.u))) yyextra->error(*yylloc, "Integer overflow", yytext); return UINTCONSTANT; } int floatsuffix_check(TParseContext* context) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); if (context->getShaderVersion() < 300) { context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); return 0; } std::string text = yytext; text.resize(text.size() - 1); if (!strtof_clamp(text, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext); return(FLOATCONSTANT); } void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) { context->error(*lloc, reason, yyget_text(scanner)); } int int_constant(TParseContext *context) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); unsigned int u; if (!atoi_clamp(yytext, &u)) { if (context->getShaderVersion() >= 300) yyextra->error(*yylloc, "Integer overflow", yytext); else yyextra->warning(*yylloc, "Integer overflow", yytext); } yylval->lex.i = static_cast(u); return INTCONSTANT; } int float_constant(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; if (!strtof_clamp(yytext, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext); return FLOATCONSTANT; } int yuvcscstandardext_constant(TParseContext *context) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); yyscan_t yyscanner = (yyscan_t) context->getScanner(); // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target)) { yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return YUVCSCSTANDARDEXTCONSTANT; } yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); return check_type(yyscanner); } int glslang_initialize(TParseContext* context) { yyscan_t scanner = NULL; if (yylex_init_extra(context, &scanner)) return 1; context->setScanner(scanner); return 0; } int glslang_finalize(TParseContext* context) { yyscan_t scanner = context->getScanner(); if (scanner == NULL) return 0; context->setScanner(NULL); yylex_destroy(scanner); return 0; } int glslang_scan(size_t count, const char* const string[], const int length[], TParseContext* context) { yyrestart(NULL, context->getScanner()); yyset_column(0, context->getScanner()); yyset_lineno(1, context->getScanner()); // Initialize preprocessor. angle::pp::Preprocessor *preprocessor = &context->getPreprocessor(); if (!preprocessor->init(count, string, length)) return 1; // Define extension macros. const TExtensionBehavior& extBehavior = context->extensionBehavior(); for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end(); ++iter) { // OVR_multiview should not be defined for WebGL spec'ed shaders. if (sh::IsWebGLBasedSpec(context->getShaderSpec()) && iter->first == TExtension::OVR_multiview) { continue; } preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1); } if (context->getFragmentPrecisionHigh()) preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec())); return 0; }