blob: d65111813bcaddc5e05ad18377cfa70199070b47 [file] [log] [blame]
/*
//
// Copyright (c) 2002-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 Lex specification 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_parser.sh.
*/
%top{
//
// 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_parser.sh. DO NOT EDIT!
}
%{
#include "Input.h"
#include "Lexer.h"
#include "Token.h"
typedef std::string YYSTYPE;
typedef pp::Token::Location YYLTYPE;
#define YY_USER_ACTION \
do { \
yylloc->line = yylineno; \
yylloc->string = 0; \
} while(0);
// Suppress the default implementation of YY_INPUT which generated
// compiler warnings.
#define YY_INPUT
%}
%option nounput never-interactive
%option reentrant bison-bridge bison-locations
%option prefix="pp"
%option extra-type="pp::Input*"
%x COMMENT
NEWLINE \n|\r|\r\n
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?]
DECIMAL_CONSTANT [1-9][0-9]*
OCTAL_CONSTANT 0[0-7]*
HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+
DIGIT [0-9]
EXPONENT_PART [eE][+-]?{DIGIT}+
FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
%%
/* Line comment */
"//"[^\r\n]*
/* Block comment */
"/*" { BEGIN(COMMENT); }
<COMMENT>[^*\r\n]*
<COMMENT>[^*\r\n]*{NEWLINE} { ++yylineno; return '\n'; }
<COMMENT>"*"+[^*/\r\n]*
<COMMENT>"*"+[^*/\r\n]*{NEWLINE} { ++yylineno; return '\n'; }
<COMMENT>"*"+"/" { BEGIN(INITIAL); return ' '; }
# { return yytext[0]; }
{IDENTIFIER} {
yylval->assign(yytext, yyleng);
return pp::Token::IDENTIFIER;
}
{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} {
yylval->assign(yytext, yyleng);
return pp::Token::CONST_INT;
}
({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
yylval->assign(yytext, yyleng);
return pp::Token::CONST_FLOAT;
}
/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
/* Rule to catch all invalid integers and floats. */
({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) {
yylval->assign(yytext, yyleng);
return pp::Token::INVALID_NUMBER;
}
"++" { return pp::Token::OP_INC; }
"--" { return pp::Token::OP_DEC; }
"<<" { return pp::Token::OP_LEFT; }
">>" { return pp::Token::OP_RIGHT; }
"<=" { return pp::Token::OP_LE; }
">=" { return pp::Token::OP_GE; }
"==" { return pp::Token::OP_EQ; }
"!=" { return pp::Token::OP_NE; }
"&&" { return pp::Token::OP_AND; }
"^^" { return pp::Token::OP_XOR; }
"||" { return pp::Token::OP_OR; }
"+=" { return pp::Token::OP_ADD_ASSIGN; }
"-=" { return pp::Token::OP_SUB_ASSIGN; }
"*=" { return pp::Token::OP_MUL_ASSIGN; }
"/=" { return pp::Token::OP_DIV_ASSIGN; }
"%=" { return pp::Token::OP_MOD_ASSIGN; }
"<<=" { return pp::Token::OP_LEFT_ASSIGN; }
">>=" { return pp::Token::OP_RIGHT_ASSIGN; }
"&=" { return pp::Token::OP_AND_ASSIGN; }
"^=" { return pp::Token::OP_XOR_ASSIGN; }
"|=" { return pp::Token::OP_OR_ASSIGN; }
{PUNCTUATOR} { return yytext[0]; }
[ \t\v\f]+ { return ' '; }
{NEWLINE} {
++yylineno;
return '\n';
}
. {
yylval->assign(yytext, yyleng);
return pp::Token::INVALID_CHARACTER;
}
<*><<EOF>> { yyterminate(); }
%%
int ppwrap(yyscan_t scanner)
{
pp::Input* input = yyget_extra(scanner);
// Delete the current buffer before switching to the next one.
YY_BUFFER_STATE buffer = static_cast<YY_BUFFER_STATE>(input->buffer);
if (buffer != NULL)
{
yy_delete_buffer(buffer, scanner);
input->buffer = NULL;
}
int index = std::min(input->index + 1, input->count);
if (index == input->count)
return 1; // EOF reached.
int length = input->length ? input->length[index] : -1;
if (length < 0) // NULL terminated string.
buffer = yy_scan_string(input->string[index], scanner);
else
buffer = yy_scan_bytes(input->string[index], length, scanner);
// TODO(alokp): Increment token location.
input->index = index;
input->buffer = buffer;
return 0;
}
namespace pp {
int Lexer::lex(Token* token)
{
bool leadingSpace = false;
token->type = yylex(&token->value, &token->location, mHandle);
while (token->type == ' ')
{
leadingSpace = true;
token->type = yylex(&token->value, &token->location, mHandle);
}
token->setHasLeadingSpace(leadingSpace);
return token->type;
}
bool Lexer::initLexer()
{
if ((mHandle == NULL) && yylex_init_extra(&mInput, &mHandle))
return false;
// Setup first scan string.
mInput.index = -1;
ppwrap(mHandle);
return true;
}
void Lexer::destroyLexer()
{
if (mHandle == NULL)
return;
YY_BUFFER_STATE buffer = static_cast<YY_BUFFER_STATE>(mInput.buffer);
if (buffer != NULL)
{
yy_delete_buffer(buffer, mHandle);
mInput.buffer = NULL;
}
yylex_destroy(mHandle);
mHandle = NULL;
}
} // namespace pp