/* // // 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 HASH_DEFINE_OBJ HASH_DEFINE_FUNC %token INT_CONSTANT FLOAT_CONSTANT IDENTIFIER %type operator %type conditional_token token %type 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