3
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
4
// Use of this source code is governed by a BSD-style license that can be
5
// found in the LICENSE file.
8
This file contains the Lex specification for GLSL ES preprocessor.
9
Based on Microsoft Visual Studio 2010 Preprocessor Grammar:
10
http://msdn.microsoft.com/en-us/library/2scxys89.aspx
12
IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
17
// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
18
// Use of this source code is governed by a BSD-style license that can be
19
// found in the LICENSE file.
22
// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
26
#include "Tokenizer.h"
28
#include "Diagnostics.h"
32
// Triggered by the auto-generated yy_fatal_error function.
33
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
36
typedef std::string YYSTYPE;
37
typedef pp::SourceLocation YYLTYPE;
39
// Use the unused yycolumn variable to track file (string) number.
40
#define yyfileno yycolumn
42
#define YY_USER_INIT \
46
yyextra->leadingSpace = false; \
47
yyextra->lineStart = true; \
50
#define YY_USER_ACTION \
53
pp::Input* input = &yyextra->input; \
54
pp::Input::Location* scanLoc = &yyextra->scanLoc; \
55
while ((scanLoc->sIndex < input->count()) && \
56
(scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
58
scanLoc->cIndex -= input->length(scanLoc->sIndex++); \
59
++yyfileno; yylineno = 1; \
61
yylloc->file = yyfileno; \
62
yylloc->line = yylineno; \
63
scanLoc->cIndex += yyleng; \
66
#define YY_INPUT(buf, result, maxSize) \
67
result = yyextra->input.read(buf, maxSize);
71
%option noyywrap nounput never-interactive
72
%option reentrant bison-bridge bison-locations
74
%option extra-type="pp::Tokenizer::Context*"
78
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
79
PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?]
81
DECIMAL_CONSTANT [1-9][0-9]*
82
OCTAL_CONSTANT 0[0-7]*
83
HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+
86
EXPONENT_PART [eE][+-]?{DIGIT}+
87
FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
95
/* Line breaks are just counted - not returned. */
96
/* The comment is replaced by a single space. */
97
"/*" { BEGIN(COMMENT); }
100
<COMMENT>{NEWLINE} { ++yylineno; }
102
yyextra->leadingSpace = true;
107
// # is only valid at start of line for preprocessor directives.
108
yylval->assign(1, yytext[0]);
109
return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER;
113
yylval->assign(yytext, yyleng);
114
return pp::Token::IDENTIFIER;
117
{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} {
118
yylval->assign(yytext, yyleng);
119
return pp::Token::CONST_INT;
122
({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
123
yylval->assign(yytext, yyleng);
124
return pp::Token::CONST_FLOAT;
127
/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
128
/* Rule to catch all invalid integers and floats. */
129
({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) {
130
yylval->assign(yytext, yyleng);
131
return pp::Token::PP_NUMBER;
135
yylval->assign(yytext, yyleng);
136
return pp::Token::OP_INC;
139
yylval->assign(yytext, yyleng);
140
return pp::Token::OP_DEC;
143
yylval->assign(yytext, yyleng);
144
return pp::Token::OP_LEFT;
147
yylval->assign(yytext, yyleng);
148
return pp::Token::OP_RIGHT;
151
yylval->assign(yytext, yyleng);
152
return pp::Token::OP_LE;
155
yylval->assign(yytext, yyleng);
156
return pp::Token::OP_GE;
159
yylval->assign(yytext, yyleng);
160
return pp::Token::OP_EQ;
163
yylval->assign(yytext, yyleng);
164
return pp::Token::OP_NE;
167
yylval->assign(yytext, yyleng);
168
return pp::Token::OP_AND;
171
yylval->assign(yytext, yyleng);
172
return pp::Token::OP_XOR;
175
yylval->assign(yytext, yyleng);
176
return pp::Token::OP_OR;
179
yylval->assign(yytext, yyleng);
180
return pp::Token::OP_ADD_ASSIGN;
183
yylval->assign(yytext, yyleng);
184
return pp::Token::OP_SUB_ASSIGN;
187
yylval->assign(yytext, yyleng);
188
return pp::Token::OP_MUL_ASSIGN;
191
yylval->assign(yytext, yyleng);
192
return pp::Token::OP_DIV_ASSIGN;
195
yylval->assign(yytext, yyleng);
196
return pp::Token::OP_MOD_ASSIGN;
199
yylval->assign(yytext, yyleng);
200
return pp::Token::OP_LEFT_ASSIGN;
203
yylval->assign(yytext, yyleng);
204
return pp::Token::OP_RIGHT_ASSIGN;
207
yylval->assign(yytext, yyleng);
208
return pp::Token::OP_AND_ASSIGN;
211
yylval->assign(yytext, yyleng);
212
return pp::Token::OP_XOR_ASSIGN;
215
yylval->assign(yytext, yyleng);
216
return pp::Token::OP_OR_ASSIGN;
220
yylval->assign(1, yytext[0]);
224
[ \t\v\f]+ { yyextra->leadingSpace = true; }
228
yylval->assign(1, '\n');
233
yylval->assign(1, yytext[0]);
234
return pp::Token::PP_OTHER;
238
// YY_USER_ACTION is not invoked for handling EOF.
239
// Set the location for EOF token manually.
240
pp::Input* input = &yyextra->input;
241
pp::Input::Location* scanLoc = &yyextra->scanLoc;
242
int sIndexMax = std::max(0, input->count() - 1);
243
if (scanLoc->sIndex != sIndexMax)
245
// We can only reach here if there are empty strings at the
247
scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
248
yyfileno = sIndexMax; yylineno = 1;
250
yylloc->file = yyfileno;
251
yylloc->line = yylineno;
254
if (YY_START == COMMENT)
256
yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT,
257
pp::SourceLocation(yyfileno, yylineno),
267
// TODO(alokp): Maximum token length should ideally be specified by
268
// the preprocessor client, i.e., the compiler.
269
const size_t Tokenizer::kMaxTokenLength = 256;
271
Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
273
mContext.diagnostics = diagnostics;
276
Tokenizer::~Tokenizer()
281
bool Tokenizer::init(int count, const char* const string[], const int length[])
283
if (count < 0) return false;
284
if ((count > 0) && (string == 0)) return false;
286
mContext.input = Input(count, string, length);
287
return initScanner();
290
void Tokenizer::setFileNumber(int file)
292
// We use column number as file number.
293
// See macro yyfileno.
294
yyset_column(file, mHandle);
297
void Tokenizer::setLineNumber(int line)
299
yyset_lineno(line, mHandle);
302
void Tokenizer::lex(Token* token)
304
token->type = yylex(&token->text, &token->location, mHandle);
305
if (token->text.size() > kMaxTokenLength)
307
mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
308
token->location, token->text);
309
token->text.erase(kMaxTokenLength);
314
token->setAtStartOfLine(mContext.lineStart);
315
mContext.lineStart = token->type == '\n';
317
token->setHasLeadingSpace(mContext.leadingSpace);
318
mContext.leadingSpace = false;
321
bool Tokenizer::initScanner()
323
if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
326
yyrestart(0, mHandle);
330
void Tokenizer::destroyScanner()
335
yylex_destroy(mHandle);