Edit

kc3-lang/angle/src/compiler/preprocessor/new/pp.y

Branch :

  • Show log

    Commit

  • Author : alokp@chromium.org
    Date : 2011-09-13 04:10:41
    Hash : 16efbbae
    Message : Complete implementation for handling #define directive. Review URL: http://codereview.appspot.com/4963062 git-svn-id: https://angleproject.googlecode.com/svn/trunk@752 736b8ea6-26fd-11df-bfd4-992fa37f6226

  • src/compiler/preprocessor/new/pp.y
  • /*
    //
    // Copyright (c) 2011 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 Yacc grammar for GLSL ES preprocessor.
    Based on Microsoft Visual Studio 2010 Preprocessor Grammar:
    http://msdn.microsoft.com/en-us/library/2scxys89.aspx
    
    IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glsl_parser.sh,
    WHICH GENERATES THE GLSL ES PARSER.
    */
    
    %{
    //
    // Copyright (c) 2011 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_glslang_parser.sh. DO NOT EDIT!
    
    #include "Context.h"
    
    #define YYLEX_PARAM context->lexer()
    #define YYDEBUG 1
    %}
    
    %pure-parser
    %name-prefix="pp"
    %locations
    %parse-param {pp::Context* context}
    
    %union {
        int ival;
        std::string* sval;
        pp::Token* tval;
        pp::TokenVector* tlist;
    }
    
    %{
    extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer);
    static void yyerror(YYLTYPE* llocp,
                        pp::Context* context,
                        const char* reason);
    
    static void pushConditionalBlock(pp::Context* context, bool condition);
    static void popConditionalBlock(pp::Context* context);
    %}
    
    %token HASH HASH_UNDEF
    %token HASH_IF HASH_IFDEF HASH_IFNDEF HASH_ELSE HASH_ELIF HASH_ENDIF DEFINED
    %token HASH_ERROR HASH_PRAGMA HASH_EXTENSION HASH_VERSION HASH_LINE
    %token <sval> HASH_DEFINE_OBJ HASH_DEFINE_FUNC
    %token <sval> INT_CONSTANT FLOAT_CONSTANT IDENTIFIER
    %type <ival> operator
    %type <tval> conditional_token token
    %type <tlist> parameter_list replacement_list conditional_list token_list
    %%
    
    input
        : /* empty */
        | input line
    ;
    
    line
        : text_line
        | control_line
    ;
    
    text_line
        : '\n'
        | token_list '\n' {
            // TODO(alokp): Expand macros.
            pp::TokenVector* out = context->output();
            out->insert(out->end(), $1->begin(), $1->end());
            delete $1;
        }
    ;
    
    control_line
        : HASH '\n'
        | HASH_DEFINE_OBJ replacement_list '\n' {
            context->defineMacro(@1.first_line, pp::Macro::kTypeObj, $1, NULL, $2);
        }
        | HASH_DEFINE_FUNC '(' parameter_list ')' replacement_list '\n' {
            context->defineMacro(@1.first_line, pp::Macro::kTypeFunc, $1, $3, $5);
        }
        | HASH_UNDEF IDENTIFIER '\n' {
            context->undefineMacro($2);
        }
        | HASH_IF conditional_list '\n' {
            pushConditionalBlock(context, $2 ? true : false);
        }
        | HASH_IFDEF IDENTIFIER '\n' {
            pushConditionalBlock(context, context->isMacroDefined($2));
        }
        | HASH_IFNDEF IDENTIFIER '\n' {
            pushConditionalBlock(context, !context->isMacroDefined($2));
        }
        | HASH_ELIF conditional_list '\n' {
        }
        | HASH_ELSE '\n' {
        }
        | HASH_ENDIF '\n' {
            popConditionalBlock(context);
        }
        | HASH_ERROR '\n'
        | HASH_PRAGMA '\n'
        | HASH_EXTENSION '\n'
        | HASH_VERSION '\n'
        | HASH_LINE '\n'
    ;
    
    replacement_list
        : /* empty */ { $$ = NULL; }
        | token_list
    
    parameter_list
        : /* empty */ { $$ = NULL; }
        | IDENTIFIER {
            $$ = new pp::TokenVector;
            $$->push_back(new pp::Token(@1.first_line, IDENTIFIER, $1));
        }
        | parameter_list ',' IDENTIFIER {
            $$ = $1;
            $$->push_back(new pp::Token(@3.first_line, IDENTIFIER, $3));
        }
    
    conditional_list
        : conditional_token {
            $$ = new pp::TokenVector;
            $$->push_back($1);
        }
        | conditional_list conditional_token {
            $$ = $1;
            $$->push_back($2);
        }
    ;
    
    token_list
        : token {
            $$ = new pp::TokenVector;
            $$->push_back($1);
        }
        | token_list token {
            $$ = $1;
            $$->push_back($2);
        }
    ;
    
    conditional_token
        : DEFINED IDENTIFIER {
        }
        | DEFINED '(' IDENTIFIER ')' {
        }
        | token
    ;
    
    token
        : operator {
            $$ = new pp::Token(@1.first_line, $1, NULL);
        }
        | INT_CONSTANT {
            $$ = new pp::Token(@1.first_line, INT_CONSTANT, $1);
        }
        | FLOAT_CONSTANT {
            $$ = new pp::Token(@1.first_line, FLOAT_CONSTANT, $1);
        }
        | IDENTIFIER {
            $$ = new pp::Token(@1.first_line, IDENTIFIER, $1);
        }
    ;
    
    operator
        : '[' { $$ = '['; }
        | ']' { $$ = ']'; }
        | '<' { $$ = '<'; }
        | '>' { $$ = '>'; }
        | '(' { $$ = '('; }
        | ')' { $$ = ')'; }
        | '{' { $$ = '{'; }
        | '}' { $$ = '}'; }
        | '.' { $$ = '.'; }
        | '+' { $$ = '+'; }
        | '-' { $$ = '-'; }
        | '/' { $$ = '/'; }
        | '*' { $$ = '*'; }
        | '%' { $$ = '%'; }
        | '^' { $$ = '^'; }
        | '|' { $$ = '|'; }
        | '&' { $$ = '&'; }
        | '~' { $$ = '~'; }
        | '=' { $$ = '='; }
        | '!' { $$ = '!'; }
        | ':' { $$ = ':'; }
        | ';' { $$ = ';'; }
        | ',' { $$ = ','; }
        | '?' { $$ = '?'; }
    ;
    
    %%
    
    void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason)
    {
    }
    
    void pushConditionalBlock(pp::Context* context, bool condition)
    {
    }
    
    void popConditionalBlock(pp::Context* context)
    {
    }
    
    namespace pp {
    bool Context::parse()
    {
        yydebug = 1;
        return yyparse(this) == 0 ? true : false;
    }
    }  // namespace pp