| /* |
| // |
| // 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 |
| |