| /* |
| // |
| // 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 generate_parser.sh, |
| WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). |
| */ |
| |
| %top{ |
| // |
| // Copyright 2012 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 is auto-generated by generate_parser.sh. DO NOT EDIT! |
| |
| /* clang-format off */ |
| |
| // 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.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); |
| static int ES2_reserved_ES3_keyword(TParseContext *context, int token); |
| static int ES2_keyword_ES3_reserved(TParseContext *context, int token); |
| static int ES2_ident_ES3_keyword(TParseContext *context, int token); |
| static int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token); |
| static int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token); |
| static int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token); |
| static int ES2_extension_ES3_keyword_else_reserved(TParseContext *context, TExtension extension, int token); |
| static int ES3_extension_keyword_else_ident(TParseContext *context, TExtension extension, int token); |
| static int ES2_ident_ES3_reserved_ES3_1_extension_keyword(TParseContext *context, TExtension extension, int token); |
| static int ES3_extension_and_ES3_1_keyword_ES3_reserved_else_ident(TParseContext *context, TExtension extension, 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 ES2_and_ES3_ident_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 ES2_ident_ES3_keyword(context, CASE); } |
| "default" { return ES2_reserved_ES3_keyword(context, DEFAULT); } |
| |
| "centroid" { return ES2_ident_ES3_keyword(context, CENTROID); } |
| "flat" { return ES2_reserved_ES3_keyword(context, FLAT); } |
| "smooth" { return ES2_ident_ES3_keyword(context, SMOOTH); } |
| |
| "in" { return IN_QUAL; } |
| "out" { return OUT_QUAL; } |
| "inout" { return INOUT_QUAL; } |
| "shared" { return ES2_and_ES3_ident_ES3_1_keyword(context, SHARED); } |
| |
| "float" { return FLOAT_TYPE; } |
| "int" { return INT_TYPE; } |
| "uint" { return ES2_ident_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 ES2_ident_ES3_keyword(context, MATRIX2); } |
| "mat3x3" { return ES2_ident_ES3_keyword(context, MATRIX3); } |
| "mat4x4" { return ES2_ident_ES3_keyword(context, MATRIX4); } |
| |
| "mat2x3" { return ES2_ident_ES3_keyword(context, MATRIX2x3); } |
| "mat3x2" { return ES2_ident_ES3_keyword(context, MATRIX3x2); } |
| "mat2x4" { return ES2_ident_ES3_keyword(context, MATRIX2x4); } |
| "mat4x2" { return ES2_ident_ES3_keyword(context, MATRIX4x2); } |
| "mat3x4" { return ES2_ident_ES3_keyword(context, MATRIX3x4); } |
| "mat4x3" { return ES2_ident_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 ES2_ident_ES3_keyword(context, UVEC2); } |
| "uvec3" { return ES2_ident_ES3_keyword(context, UVEC3); } |
| "uvec4" { return ES2_ident_ES3_keyword(context, UVEC4); } |
| |
| "sampler2D" { return SAMPLER2D; } |
| "samplerCube" { return SAMPLERCUBE; } |
| "samplerExternalOES" { return SAMPLER_EXTERNAL_OES; } |
| "sampler3D" { return ES2_extension_ES3_keyword_else_reserved(context, TExtension::OES_texture_3D, SAMPLER3D); } |
| "sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); } |
| "sampler2DRect" { return SAMPLER2DRECT; } |
| "sampler2DArray" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAY); } |
| "sampler2DMS" { return ES3_extension_and_ES3_1_keyword_ES3_reserved_else_ident(context, TExtension::ANGLE_texture_multisample, SAMPLER2DMS); } |
| "isampler2D" { return ES2_ident_ES3_keyword(context, ISAMPLER2D); } |
| "isampler3D" { return ES2_ident_ES3_keyword(context, ISAMPLER3D); } |
| "isamplerCube" { return ES2_ident_ES3_keyword(context, ISAMPLERCUBE); } |
| "isampler2DArray" { return ES2_ident_ES3_keyword(context, ISAMPLER2DARRAY); } |
| "isampler2DMS" { return ES3_extension_and_ES3_1_keyword_ES3_reserved_else_ident(context, TExtension::ANGLE_texture_multisample, ISAMPLER2DMS); } |
| "usampler2D" { return ES2_ident_ES3_keyword(context, USAMPLER2D); } |
| "usampler3D" { return ES2_ident_ES3_keyword(context, USAMPLER3D); } |
| "usamplerCube" { return ES2_ident_ES3_keyword(context, USAMPLERCUBE); } |
| "usampler2DArray" { return ES2_ident_ES3_keyword(context, USAMPLER2DARRAY); } |
| "usampler2DMS" { return ES3_extension_and_ES3_1_keyword_ES3_reserved_else_ident(context, TExtension::ANGLE_texture_multisample, USAMPLER2DMS); } |
| "sampler2DShadow" { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); } |
| "samplerCubeShadow" { return ES2_ident_ES3_keyword(context, SAMPLERCUBESHADOW); } |
| "sampler2DArrayShadow" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAYSHADOW); } |
| "__samplerExternal2DY2YEXT" { return ES3_extension_keyword_else_ident(context, TExtension::EXT_YUV_target, SAMPLEREXTERNAL2DY2YEXT); } |
| "sampler2DMSArray" { return ES2_ident_ES3_reserved_ES3_1_extension_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, SAMPLER2DMSARRAY); } |
| "isampler2DMSArray" { return ES2_ident_ES3_reserved_ES3_1_extension_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, ISAMPLER2DMSARRAY); } |
| "usampler2DMSArray" { return ES2_ident_ES3_reserved_ES3_1_extension_keyword(context, TExtension::OES_texture_storage_multisample_2d_array, USAMPLER2DMSARRAY); } |
| |
| "struct" { return STRUCT; } |
| |
| "layout" { return ES2_ident_ES3_keyword(context, LAYOUT); } |
| |
| "yuvCscStandardEXT" { return ES3_extension_keyword_else_ident(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 ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2D); } |
| "iimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2D); } |
| "uimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2D); } |
| "image2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); } |
| "iimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); } |
| "uimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); } |
| "image3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE3D); } |
| "uimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE3D); } |
| "iimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE3D); } |
| "iimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); } |
| "uimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); } |
| "imageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGECUBE); } |
| "readonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, READONLY); } |
| "writeonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, WRITEONLY); } |
| "coherent" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, COHERENT); } |
| "restrict" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, RESTRICT); } |
| "volatile" { return ES2_and_ES3_reserved_ES3_1_keyword(context, VOLATILE); } |
| "atomic_uint" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, ATOMICUINT); } |
| |
| /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */ |
| "resource" | |
| "noperspective" | |
| "patch" | |
| "sample" | |
| "subroutine" | |
| "common" | |
| "partition" | |
| "active" | |
| |
| "filter" | |
| "image1D" | |
| "iimage1D" | |
| "uimage1D" | |
| "image1DArray" | |
| "iimage1DArray" | |
| "uimage1DArray" | |
| "image1DShadow" | |
| "image2DShadow" | |
| "image1DArrayShadow" | |
| "image2DArrayShadow" | |
| "imageBuffer" | |
| "iimageBuffer" | |
| "uimageBuffer" | |
| |
| "sampler1DArray" | |
| "sampler1DArrayShadow" | |
| "isampler1D" | |
| "isampler1DArray" | |
| "usampler1D" | |
| "usampler1DArray" | |
| "isampler2DRect" | |
| "usampler2DRect" | |
| "samplerBuffer" | |
| "isamplerBuffer" | |
| "usamplerBuffer" { |
| 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; } |
| |
| <FIELDS>{L}({L}|{D})* { |
| BEGIN(INITIAL); |
| yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); |
| return FIELD_SELECTION; |
| } |
| <FIELDS>[ \t\v\f\r] {} |
| <FIELDS>. { |
| yyextra->error(*yylloc, "Illegal character at fieldname start", yytext); |
| return 0; |
| } |
| |
| [ \t\v\n\f\r] { } |
| <*><<EOF>> { 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; |
| } |
| |
| 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 ES2_ident_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 ES2_ident_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_and_ES3_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 ES2_and_ES3_ident_ES3_1_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 and GLSL ES 3.00, so could be used as an identifier/type name |
| if (context->getShaderVersion() < 310) |
| { |
| yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); |
| return check_type(yyscanner); |
| } |
| |
| return token; |
| } |
| |
| int ES2_extension_ES3_keyword_else_reserved(TParseContext *context, TExtension extension, int token) |
| { |
| yyscan_t yyscanner = (yyscan_t) context->getScanner(); |
| |
| // Available with extension or ES 3.00 and above, reserved otherwise |
| if (context->isExtensionEnabled(extension) || context->getShaderVersion() >= 300) |
| { |
| return token; |
| } |
| |
| return reserved_word(yyscanner); |
| } |
| |
| int ES3_extension_keyword_else_ident(TParseContext *context, TExtension extension, int token) |
| { |
| 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(extension)) |
| { |
| return token; |
| } |
| |
| yylval->lex.string = AllocatePoolCharArray(yytext, yyleng); |
| return check_type(yyscanner); |
| } |
| |
| int ES2_ident_ES3_reserved_ES3_1_extension_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 (context->getShaderVersion() >= 310 && context->isExtensionEnabled(extension)) |
| { |
| 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_extension_and_ES3_1_keyword_ES3_reserved_else_ident(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 (context->getShaderVersion() >= 310 || (context->getShaderVersion() == 300 && context->isExtensionEnabled(extension))) |
| { |
| return token; |
| } |
| |
| 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<int>(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) { |
| preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1); |
| } |
| if (context->getFragmentPrecisionHigh()) |
| preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); |
| |
| preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec())); |
| |
| return 0; |
| } |