Edit

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

Branch :

  • Show log

    Commit

  • Author : apatrick@chromium.org
    Date : 2012-01-26 19:18:24
    Hash : e057c5dd
    Message : Fixed more warnings. Clang warns about missing case in enum glslang_lex.cpp so I disabled that one as well. MSVC, as Chromium is built at least, warns about things in its own STL headers in SymbolTable.cpp so disabled the warning for that file. esTransform.c had a struct that the compiler could not determine was initialized so I explicitly initialized it. Review URL: https://codereview.appspot.com/5577048 git-svn-id: https://angleproject.googlecode.com/svn/trunk@965 736b8ea6-26fd-11df-bfd4-992fa37f6226

  • src/compiler/glslang.l
  • /*
    //
    // Copyright (c) 2002-2010 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) 2010 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/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 int string_input(char* buf, int 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"    { 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"        { 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; }
    "sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; }
    
    "struct"       { context->lexAfterType = true; 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); }
    
    "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); }
    
    "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); }
    "fvec2"        { return reserved_word(yyscanner); }
    "fvec3"        { return reserved_word(yyscanner); }
    "fvec4"        { return reserved_word(yyscanner); }
    "dvec2"        { return reserved_word(yyscanner); }
    "dvec3"        { return reserved_word(yyscanner); }
    "dvec4"        { 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}+         { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
    0{O}+             { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
    0{D}+             { context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;}
    {D}+              { yylval->lex.i = 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; }
    
    %%
    
    extern "C" {
    // Preprocessor interface.
    #include "compiler/preprocessor/preprocess.h"
    
    #define SETUP_CONTEXT(pp) \
        TParseContext* context = (TParseContext*) pp->pC; \
        struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
    
    // Preprocessor callbacks.
    void CPPDebugLogMsg(const char *msg)
    {
        SETUP_CONTEXT(cpp);
        context->infoSink.debug.message(EPrefixNone, msg);
    }
    
    void CPPWarningToInfoLog(const char *msg)
    {
        SETUP_CONTEXT(cpp);
        context->warning(yylineno, msg, "", "");
    }
    
    void CPPShInfoLogMsg(const char *msg)
    {
        SETUP_CONTEXT(cpp);
        context->error(yylineno, msg, "", "");
        context->recover();
    }
    
    void CPPErrorToInfoLog(char *msg)
    {
        SETUP_CONTEXT(cpp);
        context->error(yylineno, msg, "", "");
        context->recover();
    }
    
    void SetLineNumber(int line)
    {
        SETUP_CONTEXT(cpp);
        int string = 0;
        DecodeSourceLoc(yylineno, &string, NULL);
        yylineno = EncodeSourceLoc(string, line);
    }
    
    void SetStringNumber(int string)
    {
        SETUP_CONTEXT(cpp);
        int line = 0;
        DecodeSourceLoc(yylineno, NULL, &line);
        yylineno = EncodeSourceLoc(string, line);
    }
    
    int GetStringNumber()
    {
        SETUP_CONTEXT(cpp);
        int string = 0;
        DecodeSourceLoc(yylineno, &string, NULL);
        return string;
    }
    
    int GetLineNumber()
    {
        SETUP_CONTEXT(cpp);
        int line = 0;
        DecodeSourceLoc(yylineno, NULL, &line);
        return line;
    }
    
    void IncLineNumber()
    {
        SETUP_CONTEXT(cpp);
        int string = 0, line = 0;
        DecodeSourceLoc(yylineno, &string, &line);
        yylineno = EncodeSourceLoc(string, ++line);
    }
    
    void DecLineNumber()
    {
        SETUP_CONTEXT(cpp);
        int string = 0, line = 0;
        DecodeSourceLoc(yylineno, &string, &line);
        yylineno = EncodeSourceLoc(string, --line);
    }
    
    void HandlePragma(const char **tokens, int numTokens)
    {
        SETUP_CONTEXT(cpp);
        if (!strcmp(tokens[0], "optimize")) {
            if (numTokens != 4) {
                CPPShInfoLogMsg("optimize pragma syntax is incorrect");
                return;
            }
            
            if (strcmp(tokens[1], "(")) {
                CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
                return;
            }
                
            if (!strcmp(tokens[2], "on"))
                context->contextPragma.optimize = true;
            else if (!strcmp(tokens[2], "off"))
                context->contextPragma.optimize = false;
            else {
                CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
                return;
            }
            
            if (strcmp(tokens[3], ")")) {
                CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
                return;
            }
        } else if (!strcmp(tokens[0], "debug")) {
            if (numTokens != 4) {
                CPPShInfoLogMsg("debug pragma syntax is incorrect");
                return;
            }
            
            if (strcmp(tokens[1], "(")) {
                CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
                return;
            }
                
            if (!strcmp(tokens[2], "on"))
                context->contextPragma.debug = true;
            else if (!strcmp(tokens[2], "off"))
                context->contextPragma.debug = false;
            else {
                CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
                return;
            }
            
            if (strcmp(tokens[3], ")")) {
                CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
                return;
            }
        } else {
    #ifdef PRAGMA_TABLE
            //
            // implementation specific pragma
            // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
            // For now, just ignore the pragma that the implementation cannot recognize
            // An Example of one such implementation for a pragma that has a syntax like
            // #pragma pragmaname(pragmavalue)
            // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
            //        
            if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {              
                TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
                TPragmaTable::iterator iter;
                iter = pragmaTable.find(TString(tokens[0]));
                if (iter != pragmaTable.end()) {
                    iter->second = tokens[2];
                } else {
                    pragmaTable[ tokens[0] ] = tokens[2];
                }        
            } else if (numTokens >= 2) {
                TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
                TPragmaTable::iterator iter;
                iter = pragmaTable.find(TString(tokens[0]));
                if (iter != pragmaTable.end()) {
                    iter->second = tokens[1];
                } else {
                    pragmaTable[ tokens[0] ] = tokens[1];
                }
            }
    #endif // PRAGMA_TABLE
        }
    }
    
    void StoreStr(char *string)
    {
        SETUP_CONTEXT(cpp);
        TString strSrc;
        strSrc = TString(string);
    
        context->HashErrMsg = context->HashErrMsg + " " + strSrc;
    }
    
    const char* GetStrfromTStr(void)
    {
        SETUP_CONTEXT(cpp);
        cpp->ErrMsg = context->HashErrMsg.c_str();
        return cpp->ErrMsg;
    }
    
    void ResetTString(void)
    {
        SETUP_CONTEXT(cpp);
        context->HashErrMsg = "";
    }
    
    TBehavior GetBehavior(const char* behavior)
    {
        if (!strcmp("require", behavior))
            return EBhRequire;
        else if (!strcmp("enable", behavior))
            return EBhEnable;
        else if (!strcmp("disable", behavior))
            return EBhDisable;
        else if (!strcmp("warn", behavior))
            return EBhWarn;
        else {
            CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
            return EBhDisable;
        }        
    }
    
    void updateExtensionBehavior(const char* extName, const char* behavior)
    {
        SETUP_CONTEXT(cpp);
        TBehavior behaviorVal = GetBehavior(behavior);
        TMap<TString, TBehavior>:: iterator iter;
        TString msg;
        
        // special cased for all extension
        if (!strcmp(extName, "all")) {
            if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
                CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");  
                return;
            } else {
                for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
                    iter->second = behaviorVal;
            }        
        } else {
            iter = context->extensionBehavior.find(TString(extName));
            if (iter == context->extensionBehavior.end()) {
                switch (behaviorVal) {
                case EBhRequire:
                    CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());  
                    break;
                case EBhEnable:
                case EBhWarn:
                case EBhDisable:
                    msg = TString("extension '") + extName + "' is not supported";
                    context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); 
                    break;
                default:
                    break;
                }
                return;
            } else
                iter->second = behaviorVal;
        }
    }
    }  // extern "C"
    
    int string_input(char* buf, int max_size, yyscan_t yyscanner) {
        int len;
    
        if ((len = yylex_CPP(buf, max_size)) == 0)
            return 0;
        if (len >= max_size) 
            YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
    
        buf[len] = ' ';
        return len+1;
    }
    
    int check_type(yyscan_t yyscanner) {
        struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
        
        int token = IDENTIFIER;
        TSymbol* symbol = yyextra->symbolTable.find(yytext);
        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;
        return yylex_destroy(scanner);
    }
    
    void glslang_scan(int count, const char* const string[], const int length[],
                      TParseContext* context) {
        yyrestart(NULL, context->scanner);
        yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
        context->AfterEOF = false;
        
        // Init preprocessor.
        cpp->pC = context;
        cpp->PaWhichStr = 0;
        cpp->PaArgv     = string;
        cpp->PaArgc     = count;
        cpp->PaStrLen   = length;
        cpp->pastFirstStatement = 0;
        ScanFromString(string[0]);
    }