OSDN Git Service

Increment the version number.
[android-x86/external-swiftshader.git] / src / Radiance / compiler / preprocessor / Tokenizer.l
1 /*
2 //
3 // Copyright (c) 2002-2013 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.
6 //
7
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
11
12 IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
13 */
14
15 %top{
16 //
17 // Copyright (c) 2011-2013 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.
20 //
21
22 // This file is auto-generated by generate_parser.sh. DO NOT EDIT!
23 }
24
25 %{
26 #include "Tokenizer.h"
27
28 #include "Diagnostics.h"
29 #include "Token.h"
30
31 #if defined(__GNUC__)
32 // Triggered by the auto-generated yy_fatal_error function.
33 #pragma GCC diagnostic ignored "-Wmissing-noreturn"
34 #endif
35
36 typedef std::string YYSTYPE;
37 typedef pp::SourceLocation YYLTYPE;
38
39 // Use the unused yycolumn variable to track file (string) number.
40 #define yyfileno yycolumn
41
42 #define YY_USER_INIT                   \
43     do {                               \
44         yyfileno = 0;                  \
45         yylineno = 1;                  \
46         yyextra->leadingSpace = false; \
47         yyextra->lineStart = true;     \
48     } while(0);
49
50 #define YY_USER_ACTION                                              \
51     do                                                              \
52     {                                                               \
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))) \
57         {                                                           \
58             scanLoc->cIndex -= input->length(scanLoc->sIndex++);    \
59             ++yyfileno; yylineno = 1;                               \
60         }                                                           \
61         yylloc->file = yyfileno;                                    \
62         yylloc->line = yylineno;                                    \
63         scanLoc->cIndex += yyleng;                                  \
64     } while(0);
65
66 #define YY_INPUT(buf, result, maxSize) \
67     result = yyextra->input.read(buf, maxSize);
68
69 %}
70
71 %option noyywrap nounput never-interactive
72 %option reentrant bison-bridge bison-locations
73 %option prefix="pp"
74 %option extra-type="pp::Tokenizer::Context*"
75 %x COMMENT
76
77 NEWLINE     \n|\r|\r\n
78 IDENTIFIER  [_a-zA-Z][_a-zA-Z0-9]*
79 PUNCTUATOR  [][<>(){}.+-/*%^|&~=!:;,?]
80
81 DECIMAL_CONSTANT      [1-9][0-9]*
82 OCTAL_CONSTANT        0[0-7]*
83 HEXADECIMAL_CONSTANT  0[xX][0-9a-fA-F]+
84
85 DIGIT                [0-9]
86 EXPONENT_PART        [eE][+-]?{DIGIT}+
87 FRACTIONAL_CONSTANT  ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
88
89 %%
90
91     /* Line comment */
92 "//"[^\r\n]*
93
94     /* Block comment */
95     /* Line breaks are just counted - not returned. */
96     /* The comment is replaced by a single space. */ 
97 "/*" { BEGIN(COMMENT); }
98 <COMMENT>[^*\r\n]+
99 <COMMENT>"*"
100 <COMMENT>{NEWLINE} { ++yylineno; }
101 <COMMENT>"*/" {
102     yyextra->leadingSpace = true;
103     BEGIN(INITIAL);
104 }
105
106 # {
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;
110 }
111
112 {IDENTIFIER} {
113     yylval->assign(yytext, yyleng);
114     return pp::Token::IDENTIFIER;
115 }
116
117 {DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} {
118     yylval->assign(yytext, yyleng);
119     return pp::Token::CONST_INT;
120 }
121
122 ({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
123     yylval->assign(yytext, yyleng);
124     return pp::Token::CONST_FLOAT;
125 }
126
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;
132 }
133
134 "++" {
135     yylval->assign(yytext, yyleng);
136     return pp::Token::OP_INC;
137 }
138 "--" {
139     yylval->assign(yytext, yyleng);
140     return pp::Token::OP_DEC;
141 }
142 "<<" {
143     yylval->assign(yytext, yyleng);
144     return pp::Token::OP_LEFT;
145 }
146 ">>" {
147     yylval->assign(yytext, yyleng);
148     return pp::Token::OP_RIGHT;
149 }
150 "<=" {
151     yylval->assign(yytext, yyleng);
152     return pp::Token::OP_LE;
153 }
154 ">=" {
155     yylval->assign(yytext, yyleng);
156     return pp::Token::OP_GE;
157 }
158 "==" {
159     yylval->assign(yytext, yyleng);
160     return pp::Token::OP_EQ;
161 }
162 "!=" {
163     yylval->assign(yytext, yyleng);
164     return pp::Token::OP_NE;
165 }
166 "&&" {
167     yylval->assign(yytext, yyleng);
168     return pp::Token::OP_AND;
169 }
170 "^^" {
171     yylval->assign(yytext, yyleng);
172     return pp::Token::OP_XOR;
173 }
174 "||" {
175     yylval->assign(yytext, yyleng);
176     return pp::Token::OP_OR;
177 }
178 "+=" {
179     yylval->assign(yytext, yyleng);
180     return pp::Token::OP_ADD_ASSIGN;
181 }
182 "-=" {
183     yylval->assign(yytext, yyleng);
184     return pp::Token::OP_SUB_ASSIGN;
185 }
186 "*=" {
187     yylval->assign(yytext, yyleng);
188     return pp::Token::OP_MUL_ASSIGN;
189 }
190 "/=" {
191     yylval->assign(yytext, yyleng);
192     return pp::Token::OP_DIV_ASSIGN;
193 }
194 "%=" {
195     yylval->assign(yytext, yyleng);
196     return pp::Token::OP_MOD_ASSIGN;
197 }
198 "<<=" {
199     yylval->assign(yytext, yyleng);
200     return pp::Token::OP_LEFT_ASSIGN;
201 }
202 ">>=" {
203     yylval->assign(yytext, yyleng);
204     return pp::Token::OP_RIGHT_ASSIGN;
205 }
206 "&=" {
207     yylval->assign(yytext, yyleng);
208     return pp::Token::OP_AND_ASSIGN;
209 }
210 "^=" {
211     yylval->assign(yytext, yyleng);
212     return pp::Token::OP_XOR_ASSIGN;
213 }
214 "|=" {
215     yylval->assign(yytext, yyleng);
216     return pp::Token::OP_OR_ASSIGN;
217 }
218
219 {PUNCTUATOR} {
220     yylval->assign(1, yytext[0]);
221     return yytext[0];
222 }
223
224 [ \t\v\f]+   { yyextra->leadingSpace = true; }
225
226 {NEWLINE} {
227     ++yylineno;
228     yylval->assign(1, '\n');
229     return '\n';
230 }
231
232 \\{NEWLINE} { ++yylineno; }
233
234 . {
235     yylval->assign(1, yytext[0]);
236     return pp::Token::PP_OTHER;
237 }
238
239 <*><<EOF>> {
240     // YY_USER_ACTION is not invoked for handling EOF.
241     // Set the location for EOF token manually.
242     pp::Input* input = &yyextra->input;
243     pp::Input::Location* scanLoc = &yyextra->scanLoc;
244     int sIndexMax = std::max(0, input->count() - 1);
245     if (scanLoc->sIndex != sIndexMax)
246     {
247         // We can only reach here if there are empty strings at the
248         // end of the input.
249         scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
250         yyfileno = sIndexMax; yylineno = 1;
251     }
252     yylloc->file = yyfileno;
253     yylloc->line = yylineno;
254     yylval->clear();
255
256     if (YY_START == COMMENT)
257     {
258         yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT,
259                                      pp::SourceLocation(yyfileno, yylineno),
260                                      "");
261     }
262     yyterminate();
263 }
264
265 %%
266
267 namespace pp {
268
269 // TODO(alokp): Maximum token length should ideally be specified by
270 // the preprocessor client, i.e., the compiler.
271 const size_t Tokenizer::kMaxTokenLength = 256;
272
273 Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
274 {
275     mContext.diagnostics = diagnostics;
276 }
277
278 Tokenizer::~Tokenizer()
279 {
280     destroyScanner();
281 }
282
283 bool Tokenizer::init(int count, const char* const string[], const int length[])
284 {
285     if (count < 0) return false;
286     if ((count > 0) && (string == 0)) return false;
287
288     mContext.input = Input(count, string, length);
289     return initScanner();
290 }
291
292 void Tokenizer::setFileNumber(int file)
293 {
294     // We use column number as file number.
295     // See macro yyfileno.
296     yyset_column(file, mHandle);
297 }
298
299 void Tokenizer::setLineNumber(int line)
300 {
301     yyset_lineno(line, mHandle);
302 }
303
304 void Tokenizer::lex(Token* token)
305 {
306     token->type = yylex(&token->text, &token->location, mHandle);
307     if (token->text.size() > kMaxTokenLength)
308     {
309         mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
310                                      token->location, token->text);
311         token->text.erase(kMaxTokenLength);
312     }
313
314     token->flags = 0;
315
316     token->setAtStartOfLine(mContext.lineStart);
317     mContext.lineStart = token->type == '\n';
318
319     token->setHasLeadingSpace(mContext.leadingSpace);
320     mContext.leadingSpace = false;
321 }
322
323 bool Tokenizer::initScanner()
324 {
325     if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
326         return false;
327
328     yyrestart(0, mHandle);
329     return true;
330 }
331
332 void Tokenizer::destroyScanner()
333 {
334     if (mHandle == NULL)
335         return;
336
337     yylex_destroy(mHandle);
338     mHandle = NULL;
339 }
340
341 }  // namespace pp
342