blob: 1cd27d6c5652f082070e5fc0458cd749028859f3 [file] [log] [blame]
/*
//
// 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!
#if defined(__GNUC__)
#elif defined(_MSC_VER)
#pragma warning(disable: 4065)
#endif
#include "Context.h"
#define YYDEBUG 1
%}
%pure-parser
%name-prefix="pp"
%locations
%parse-param {pp::Context* context}
%lex-param {pp::Context* context}
%union {
int ival;
std::string* sval;
pp::Token* tval;
pp::TokenVector* tlist;
}
%{
static int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, pp::Context* context);
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
: '[' { $$ = '['; }
| ']' { $$ = ']'; }
| '<' { $$ = '<'; }
| '>' { $$ = '>'; }
| '(' { $$ = '('; }
| ')' { $$ = ')'; }
| '{' { $$ = '{'; }
| '}' { $$ = '}'; }
| '.' { $$ = '.'; }
| '+' { $$ = '+'; }
| '-' { $$ = '-'; }
| '/' { $$ = '/'; }
| '*' { $$ = '*'; }
| '%' { $$ = '%'; }
| '^' { $$ = '^'; }
| '|' { $$ = '|'; }
| '&' { $$ = '&'; }
| '~' { $$ = '~'; }
| '=' { $$ = '='; }
| '!' { $$ = '!'; }
| ':' { $$ = ':'; }
| ';' { $$ = ';'; }
| ',' { $$ = ','; }
| '?' { $$ = '?'; }
;
%%
int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, pp::Context* context)
{
return context->lex(lvalp, llocp);
}
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