/* // // Copyright (c) 2002-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 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 (c) 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! // Ignore errors in auto-generated code. #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wswitch-enum" #elif defined(_MSC_VER) #pragma warning(disable: 4065) #pragma warning(disable: 4189) #pragma warning(disable: 4505) #pragma warning(disable: 4701) #endif } %{ #include "compiler/glslang.h" #include "compiler/ParseHelper.h" #include "compiler/preprocessor/Token.h" #include "compiler/util.h" #include "glslang_tab.h" /* windows only pragma */ #ifdef _MSC_VER #pragma warning(disable : 4102) #endif #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 int_constant(yyscan_t yyscanner); static int float_constant(yyscan_t yyscanner); %} %option noyywrap nounput never-interactive %option yylineno reentrant bison-bridge bison-locations %option extra-type="TParseContext*" D [0-9] L [a-zA-Z_] H [a-fA-F0-9] E [Ee][+-]?{D}+ O [0-7] %% "invariant" { return INVARIANT; } "highp" { return HIGH_PRECISION; } "mediump" { return MEDIUM_PRECISION; } "lowp" { return LOW_PRECISION; } "precision" { return PRECISION; } "attribute" { return ATTRIBUTE; } "const" { return CONST_QUAL; } "uniform" { return UNIFORM; } "varying" { return VARYING; } "break" { return BREAK; } "continue" { return CONTINUE; } "do" { return DO; } "for" { return FOR; } "while" { return WHILE; } "if" { return IF; } "else" { return ELSE; } "in" { return IN_QUAL; } "out" { return OUT_QUAL; } "inout" { return INOUT_QUAL; } "float" { return FLOAT_TYPE; } "int" { return INT_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; } "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; } "sampler2D" { return SAMPLER2D; } "samplerCube" { return SAMPLERCUBE; } "samplerExternalOES" { return SAMPLER_EXTERNAL_OES; } "sampler2DRect" { return SAMPLER2DRECT; } "struct" { return STRUCT; } "asm" { return reserved_word(yyscanner); } "class" { return reserved_word(yyscanner); } "union" { return reserved_word(yyscanner); } "enum" { return reserved_word(yyscanner); } "typedef" { return reserved_word(yyscanner); } "template" { return reserved_word(yyscanner); } "this" { return reserved_word(yyscanner); } "packed" { return reserved_word(yyscanner); } "goto" { return reserved_word(yyscanner); } "switch" { return reserved_word(yyscanner); } "default" { return reserved_word(yyscanner); } "inline" { return reserved_word(yyscanner); } "noinline" { return reserved_word(yyscanner); } "volatile" { return reserved_word(yyscanner); } "public" { return reserved_word(yyscanner); } "static" { return reserved_word(yyscanner); } "extern" { return reserved_word(yyscanner); } "external" { return reserved_word(yyscanner); } "interface" { return reserved_word(yyscanner); } "flat" { return reserved_word(yyscanner); } "long" { return reserved_word(yyscanner); } "short" { return reserved_word(yyscanner); } "double" { return reserved_word(yyscanner); } "half" { return reserved_word(yyscanner); } "fixed" { return reserved_word(yyscanner); } "unsigned" { return reserved_word(yyscanner); } "superp" { return reserved_word(yyscanner); } "input" { return reserved_word(yyscanner); } "output" { return reserved_word(yyscanner); } "hvec2" { return reserved_word(yyscanner); } "hvec3" { return reserved_word(yyscanner); } "hvec4" { return reserved_word(yyscanner); } "dvec2" { return reserved_word(yyscanner); } "dvec3" { return reserved_word(yyscanner); } "dvec4" { return reserved_word(yyscanner); } "fvec2" { return reserved_word(yyscanner); } "fvec3" { return reserved_word(yyscanner); } "fvec4" { return reserved_word(yyscanner); } "sampler1D" { return reserved_word(yyscanner); } "sampler3D" { return reserved_word(yyscanner); } "sampler1DShadow" { return reserved_word(yyscanner); } "sampler2DShadow" { return reserved_word(yyscanner); } "sampler3DRect" { return reserved_word(yyscanner); } "sampler2DRectShadow" { return reserved_word(yyscanner); } "sizeof" { return reserved_word(yyscanner); } "cast" { return reserved_word(yyscanner); } "namespace" { return reserved_word(yyscanner); } "using" { return reserved_word(yyscanner); } {L}({L}|{D})* { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); } 0[xX]{H}+ { return int_constant(yyscanner); } 0{O}+ { return int_constant(yyscanner); } {D}+ { return int_constant(yyscanner); } {D}+{E} { return float_constant(yyscanner); } {D}+"."{D}*({E})? { return float_constant(yyscanner); } "."{D}+({E})? { return float_constant(yyscanner); } "+=" { 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; } "." { 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; } [ \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) { pp::Token token; yyget_extra(yyscanner)->preprocessor.lex(&token); yy_size_t len = token.type == 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; TSymbol* symbol = yyextra->symbolTable.find(yytext); if (symbol && symbol->isVariable()) { TVariable* variable = static_cast(symbol); if (variable->isUserType()) 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, ""); yyextra->recover(); return 0; } void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) { context->error(*lloc, reason, yyget_text(context->scanner)); context->recover(); } int int_constant(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; if (!atoi_clamp(yytext, &(yylval->lex.i))) yyextra->warning(*yylloc, "Integer overflow", yytext, ""); return INTCONSTANT; } int float_constant(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; if (!atof_clamp(yytext, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext, ""); return FLOATCONSTANT; } int glslang_initialize(TParseContext* context) { yyscan_t scanner = NULL; if (yylex_init_extra(context, &scanner)) return 1; context->scanner = scanner; return 0; } int glslang_finalize(TParseContext* context) { yyscan_t scanner = context->scanner; if (scanner == NULL) return 0; context->scanner = NULL; yylex_destroy(scanner); return 0; } int glslang_scan(size_t count, const char* const string[], const int length[], TParseContext* context) { yyrestart(NULL, context->scanner); yyset_column(0, context->scanner); yyset_lineno(1, context->scanner); // Initialize preprocessor. if (!context->preprocessor.init(count, string, length)) return 1; context->preprocessor.setMaxTokenLength(SH_MAX_TOKEN_LENGTH); // Define extension macros. const TExtensionBehavior& extBehavior = context->extensionBehavior(); for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end(); ++iter) { context->preprocessor.predefineMacro(iter->first.c_str(), 1); } if (context->fragmentPrecisionHigh) context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); return 0; }