Home | History | Annotate | Download | only in translator
      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