Edit

kc3-lang/angle/src/compiler/glslang.l

Branch :

  • Show log

    Commit

  • Author : shannonwoods@chromium.org
    Date : 2013-05-30 00:02:41
    Hash : 96e7ba17
    Message : Skip symbol table levels with built-ins for a different shader version. TRAC #22954 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2272 736b8ea6-26fd-11df-bfd4-992fa37f6226

  • src/compiler/glslang.l
  • /*
    //
    // Copyright (c) 2002-2013 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-2013 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 yylval->lex.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);
    %}
    
    %option noyywrap nounput never-interactive
    %option yylineno reentrant bison-bridge
    %option stack
    %option extra-type="TParseContext*"
    %x COMMENT FIELDS
    
    D           [0-9]
    L           [a-zA-Z_]
    H           [a-fA-F0-9]
    E           [Ee][+-]?{D}+
    O           [0-7]
    
    %%
    
    %{
        TParseContext* context = yyextra;
    %}
    
        /* Single-line comments */
    "//"[^\n]* ;
    
        /* Multi-line comments */
    "/*"           { yy_push_state(COMMENT, yyscanner); }
    <COMMENT>. |
    <COMMENT>\n ;
    <COMMENT>"*/"  { yy_pop_state(yyscanner); }
    
    "invariant"    { return(INVARIANT); }
    "highp"        { return(HIGH_PRECISION); }
    "mediump"      { return(MEDIUM_PRECISION); }
    "lowp"         { return(LOW_PRECISION); }
    "precision"    { return(PRECISION); }
    
    "attribute"    { if (context->shaderVersion < 300) return(ATTRIBUTE); return reserved_word(yyscanner); }
    "const"        { return(CONST_QUAL); }
    "uniform"      { return(UNIFORM); }
    "varying"      { if (context->shaderVersion < 300) return(VARYING); return reserved_word(yyscanner); }
    
    "break"        { return(BREAK); }
    "continue"     { return(CONTINUE); }
    "do"           { return(DO); }
    "for"          { return(FOR); }
    "while"        { return(WHILE); }
    
    "if"           { return(IF); }
    "else"         { return(ELSE); }
    "switch"       { if (context->shaderVersion < 300) return reserved_word(yyscanner); return(SWITCH); }
    "case"         { if (context->shaderVersion < 300) return reserved_word(yyscanner); return(CASE); }
    "default"      { if (context->shaderVersion < 300) return reserved_word(yyscanner); return(DEFAULT); }
    
    "centroid"     { if (context->shaderVersion < 300) return reserved_word(yyscanner); return(CENTROID); }
    "flat"         { if (context->shaderVersion < 300) return reserved_word(yyscanner); return(FLAT); }
    "smooth"       { if (context->shaderVersion < 300) return reserved_word(yyscanner); return(SMOOTH); }
    
    "in"           { return(IN_QUAL); }
    "out"          { return(OUT_QUAL); }
    "inout"        { return(INOUT_QUAL); }
    
    "float"        { context->lexAfterType = true; return(FLOAT_TYPE); }
    "int"          { context->lexAfterType = true; return(INT_TYPE); }
    "void"         { context->lexAfterType = true; return(VOID_TYPE); }
    "bool"         { context->lexAfterType = true; return(BOOL_TYPE); }
    "true"         { yylval->lex.b = true;  return(BOOLCONSTANT); }
    "false"        { yylval->lex.b = false; return(BOOLCONSTANT); }
    
    "discard"      { return(DISCARD); }
    "return"       { return(RETURN); }
    
    "mat2"         { context->lexAfterType = true; return(MATRIX2); }
    "mat3"         { context->lexAfterType = true; return(MATRIX3); }
    "mat4"         { context->lexAfterType = true; return(MATRIX4); }
    
    "vec2"         { context->lexAfterType = true; return (VEC2); }
    "vec3"         { context->lexAfterType = true; return (VEC3); }
    "vec4"         { context->lexAfterType = true; return (VEC4); }
    "ivec2"        { context->lexAfterType = true; return (IVEC2); }
    "ivec3"        { context->lexAfterType = true; return (IVEC3); }
    "ivec4"        { context->lexAfterType = true; return (IVEC4); }
    "bvec2"        { context->lexAfterType = true; return (BVEC2); }
    "bvec3"        { context->lexAfterType = true; return (BVEC3); }
    "bvec4"        { context->lexAfterType = true; return (BVEC4); }
    
    "sampler2D"          { context->lexAfterType = true; return SAMPLER2D; }
    "samplerCube"        { context->lexAfterType = true; return SAMPLERCUBE; }
    "samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
    "sampler3D"          { if (context->shaderVersion < 300) return reserved_word(yyscanner); context->lexAfterType = true; return SAMPLER3D; }
    "sampler3DRect"      { if (context->shaderVersion < 300) return reserved_word(yyscanner); context->lexAfterType = true; return SAMPLER3DRECT; }
    "sampler2DShadow"    { if (context->shaderVersion < 300) return reserved_word(yyscanner); context->lexAfterType = true; return SAMPLER2DSHADOW; }
    "sampler2DRect"      { context->lexAfterType = true; return SAMPLER2DRECT; }
    
    "struct"       { context->lexAfterType = true; return(STRUCT); }
    
        /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
    "coherent"          |
    "restrict"          |
    "readonly"          |
    "writeonly"         |
    "resource"          |
    "atomic_uint"       |
    "noperspective"     |
    "patch"             |
    "sample"            |
    "subroutine"        |
    "common"            |
    "partition"         |
    "active"            |
    
    "filter"            |
    "image1D"           |
    "image2D"           |
    "image3D"           |
    "imageCube"	        |
    "iimage1D"          |
    "iimage2D"          |
    "iimage3D"          |
    "iimageCube"        |
    "uimage1D"          |
    "uimage2D"          |
    "uimage3D"          |
    "uimageCube"        |
    "image1DArray"      |
    "image2DArray"      |
    "iimage1DArray"     |
    "iimage2DArray"     |
    "uimage1DArray"     |
    "uimage2DArray"     |
    "image1DShadow"     |
    "image2DShadow"     |
    "image1DArrayShadow" |
    "image2DArrayShadow" |
    "imageBuffer"       |
    "iimageBuffer"      |
    "uimageBuffer"      |
    
    "sampler1DArray"    |
    "sampler1DArrayShadow" |
    "isampler1D"        |
    "isampler1DArray"   |
    "usampler1D"        |
    "usampler1DArray"   |
    "isampler2DRect"    |
    "usampler2DRect"    |
    "samplerBuffer"     |
    "isamplerBuffer"    |
    "usamplerBuffer"    |
    "sampler2DMS"       |
    "isampler2DMS"      |
    "usampler2DMS"      |
    "sampler2DMSArray"  |
    "isampler2DMSArray" |
    "usampler2DMSArray" { 
        if (context->shaderVersion < 300) {
    		yylval->lex.string = NewPoolTString(yytext); 
    	    return check_type(yyscanner); 
    	}
    	return reserved_word(yyscanner);
    }
    
        /* Reserved keywords */
    "asm"          |
    
    "class"        |
    "union"        |
    "enum"         |
    "typedef"      |
    "template"     |
    "this"         |
    "packed"       |
    
    "goto"         |
    
    "inline"       |
    "noinline"     |
    "volatile"     |
    "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 = NewPoolTString(yytext); 
       return check_type(yyscanner);
    }
    
    0[xX]{H}+         { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
    0{O}+             { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
    0{D}+             { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;}
    {D}+              { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
    
    {D}+{E}           { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
    {D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
    "."{D}+({E})?     { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
    
    "+="            {  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); }
    ";"             { context->lexAfterType = false; return(SEMICOLON); }
    ("{"|"<%")      { context->lexAfterType = false; return(LEFT_BRACE); }
    ("}"|"%>")      { return(RIGHT_BRACE); }
    ","             { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
    ":"             { return(COLON); }
    "="             { context->lexAfterType = false; return(EQUAL); }
    "("             { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
    ")"             { context->inTypeParen = false; 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 = NewPoolTString(yytext); 
        return FIELD_SELECTION;
    }
    <FIELDS>[ \t\v\f\r] {}
    
    [ \t\v\n\f\r]   {  }
    <*><<EOF>>      { context->AfterEOF = true; yyterminate(); }
    <*>.            { context->warning(yylineno, "Unknown char", yytext, ""); 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_lineno(EncodeSourceLoc(token.location.file, 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, yyextra->shaderVersion);
        if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
            TVariable* variable = static_cast<TVariable*>(symbol);
            if (variable->isUserType()) {
                yyextra->lexAfterType = true;
                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(yylineno, "Illegal use of reserved word", yytext, "");
        yyextra->recover();
        return 0;
    }
    
    void yyerror(TParseContext* context, const char* reason) {
        struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
    
        if (context->AfterEOF) {
            context->error(yylineno, reason, "unexpected EOF");
        } else {
            context->error(yylineno, reason, yytext);
        }
        context->recover();
    }
    
    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_lineno(EncodeSourceLoc(0, 1), context->scanner);
        context->AfterEOF = false;
    
        // Initialize preprocessor.
        if (!context->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) {
            context->preprocessor.predefineMacro(iter->first.c_str(), 1);
        }
        if (context->fragmentPrecisionHigh)
            context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
    
        return 0;
    }