blob: 1cfb970f0715e38a65652d2f49e28700f10ff6c6 [file] [log] [blame]
alokp@chromium.org4e4b8072011-08-07 05:36:04 +00001/*
2//
shannon.woods%transgaming.com@gtempaccount.combcde56f2013-04-13 03:32:12 +00003// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org4e4b8072011-08-07 05:36:04 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8This file contains the Lex specification for GLSL ES preprocessor.
9Based on Microsoft Visual Studio 2010 Preprocessor Grammar:
10http://msdn.microsoft.com/en-us/library/2scxys89.aspx
11
12IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
13*/
14
15%top{
16//
shannon.woods%transgaming.com@gtempaccount.combcde56f2013-04-13 03:32:12 +000017// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000018// 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%{
alokp@chromium.org04d7d222012-05-16 19:24:07 +000026#include "Tokenizer.h"
shannonwoods@chromium.org8ddaf5c2013-05-30 00:13:08 +000027#include "length_limits.h"
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000028
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000029#include "DiagnosticsBase.h"
alokp@chromium.orgd089d112012-04-13 17:05:12 +000030#include "Token.h"
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000031
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +000032#if defined(__GNUC__)
33// Triggered by the auto-generated yy_fatal_error function.
34#pragma GCC diagnostic ignored "-Wmissing-noreturn"
35#endif
36
alokp@chromium.org4b2a5222012-04-03 17:19:42 +000037typedef std::string YYSTYPE;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000038typedef pp::SourceLocation YYLTYPE;
alokp@chromium.org4b2a5222012-04-03 17:19:42 +000039
alokp@chromium.org98eec912012-05-01 10:04:08 +000040// Use the unused yycolumn variable to track file (string) number.
41#define yyfileno yycolumn
42
alokp@chromium.org04d7d222012-05-16 19:24:07 +000043#define YY_USER_INIT \
44 do { \
45 yyfileno = 0; \
46 yylineno = 1; \
47 yyextra->leadingSpace = false; \
48 yyextra->lineStart = true; \
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000049 } while(0);
alokp@chromium.orgb81c4012011-08-21 06:53:11 +000050
alokp@chromium.org19d7aa62012-05-31 17:34:05 +000051#define YY_USER_ACTION \
52 do \
53 { \
54 pp::Input* input = &yyextra->input; \
55 pp::Input::Location* scanLoc = &yyextra->scanLoc; \
56 while ((scanLoc->sIndex < input->count()) && \
57 (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
58 { \
59 scanLoc->cIndex -= input->length(scanLoc->sIndex++); \
60 ++yyfileno; yylineno = 1; \
61 } \
62 yylloc->file = yyfileno; \
63 yylloc->line = yylineno; \
64 scanLoc->cIndex += yyleng; \
alokp@chromium.org98eec912012-05-01 10:04:08 +000065 } while(0);
66
67#define YY_INPUT(buf, result, maxSize) \
alokp@chromium.org30a487c2012-05-02 17:30:46 +000068 result = yyextra->input.read(buf, maxSize);
alokp@chromium.org128d9192012-04-26 22:39:21 +000069
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000070%}
71
alokp@chromium.org98eec912012-05-01 10:04:08 +000072%option noyywrap nounput never-interactive
alokp@chromium.orgd08bb0c2012-04-23 19:27:13 +000073%option reentrant bison-bridge bison-locations
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000074%option prefix="pp"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000075%option extra-type="pp::Tokenizer::Context*"
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +000076%x COMMENT
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000077
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +000078NEWLINE \n|\r|\r\n
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000079IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
80PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?]
81
shannonwoods@chromium.orgc8100b82013-05-30 00:20:34 +000082DECIMAL_CONSTANT [1-9][0-9]*[uU]?
83OCTAL_CONSTANT 0[0-7]*[uU]?
84HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+[uU]?
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000085
alokp@chromium.orgb81c4012011-08-21 06:53:11 +000086DIGIT [0-9]
87EXPONENT_PART [eE][+-]?{DIGIT}+
88FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
89
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000090%%
91
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +000092 /* Line comment */
93"//"[^\r\n]*
94
95 /* Block comment */
alokp@chromium.orga11a6ab2012-04-27 10:00:38 +000096 /* Line breaks are just counted - not returned. */
97 /* The comment is replaced by a single space. */
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000098"/*" { BEGIN(COMMENT); }
alokp@chromium.orga11a6ab2012-04-27 10:00:38 +000099<COMMENT>[^*\r\n]+
100<COMMENT>"*"
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000101<COMMENT>{NEWLINE} { ++yylineno; }
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000102<COMMENT>"*/" {
103 yyextra->leadingSpace = true;
104 BEGIN(INITIAL);
105}
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +0000106
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000107# {
108 // # is only valid at start of line for preprocessor directives.
alokp@chromium.org432d6fc2012-06-27 22:13:21 +0000109 yylval->assign(1, yytext[0]);
110 return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000111}
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000112
113{IDENTIFIER} {
alokp@chromium.org4b2a5222012-04-03 17:19:42 +0000114 yylval->assign(yytext, yyleng);
115 return pp::Token::IDENTIFIER;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000116}
117
shannonwoods@chromium.org3f83e292013-05-30 00:21:34 +0000118({DECIMAL_CONSTANT}[uU]?)|({OCTAL_CONSTANT}[uU]?)|({HEXADECIMAL_CONSTANT}[uU]?) {
alokp@chromium.org4b2a5222012-04-03 17:19:42 +0000119 yylval->assign(yytext, yyleng);
120 return pp::Token::CONST_INT;
alokp@chromium.orgb81c4012011-08-21 06:53:11 +0000121}
122
123({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
alokp@chromium.org4b2a5222012-04-03 17:19:42 +0000124 yylval->assign(yytext, yyleng);
125 return pp::Token::CONST_FLOAT;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000126}
127
alokp@chromium.org78a35192012-04-19 17:16:26 +0000128 /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
129 /* Rule to catch all invalid integers and floats. */
130({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) {
alokp@chromium.org432d6fc2012-06-27 22:13:21 +0000131 yylval->assign(yytext, yyleng);
132 return pp::Token::PP_NUMBER;
alokp@chromium.org78a35192012-04-19 17:16:26 +0000133}
134
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000135"++" {
136 yylval->assign(yytext, yyleng);
137 return pp::Token::OP_INC;
138}
139"--" {
140 yylval->assign(yytext, yyleng);
141 return pp::Token::OP_DEC;
142}
143"<<" {
144 yylval->assign(yytext, yyleng);
145 return pp::Token::OP_LEFT;
146}
147">>" {
148 yylval->assign(yytext, yyleng);
149 return pp::Token::OP_RIGHT;
150}
151"<=" {
152 yylval->assign(yytext, yyleng);
153 return pp::Token::OP_LE;
154}
155">=" {
156 yylval->assign(yytext, yyleng);
157 return pp::Token::OP_GE;
158}
159"==" {
160 yylval->assign(yytext, yyleng);
161 return pp::Token::OP_EQ;
162}
163"!=" {
164 yylval->assign(yytext, yyleng);
165 return pp::Token::OP_NE;
166}
167"&&" {
168 yylval->assign(yytext, yyleng);
169 return pp::Token::OP_AND;
170}
171"^^" {
172 yylval->assign(yytext, yyleng);
173 return pp::Token::OP_XOR;
174}
175"||" {
176 yylval->assign(yytext, yyleng);
177 return pp::Token::OP_OR;
178}
179"+=" {
180 yylval->assign(yytext, yyleng);
181 return pp::Token::OP_ADD_ASSIGN;
182}
183"-=" {
184 yylval->assign(yytext, yyleng);
185 return pp::Token::OP_SUB_ASSIGN;
186}
187"*=" {
188 yylval->assign(yytext, yyleng);
189 return pp::Token::OP_MUL_ASSIGN;
190}
191"/=" {
192 yylval->assign(yytext, yyleng);
193 return pp::Token::OP_DIV_ASSIGN;
194}
195"%=" {
196 yylval->assign(yytext, yyleng);
197 return pp::Token::OP_MOD_ASSIGN;
198}
199"<<=" {
200 yylval->assign(yytext, yyleng);
201 return pp::Token::OP_LEFT_ASSIGN;
202}
203">>=" {
204 yylval->assign(yytext, yyleng);
205 return pp::Token::OP_RIGHT_ASSIGN;
206}
207"&=" {
208 yylval->assign(yytext, yyleng);
209 return pp::Token::OP_AND_ASSIGN;
210}
211"^=" {
212 yylval->assign(yytext, yyleng);
213 return pp::Token::OP_XOR_ASSIGN;
214}
215"|=" {
216 yylval->assign(yytext, yyleng);
217 return pp::Token::OP_OR_ASSIGN;
218}
alokp@chromium.org3f990c42012-04-03 19:50:35 +0000219
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000220{PUNCTUATOR} {
221 yylval->assign(1, yytext[0]);
222 return yytext[0];
223}
224
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000225[ \t\v\f]+ { yyextra->leadingSpace = true; }
alokp@chromium.orgd08bb0c2012-04-23 19:27:13 +0000226
227{NEWLINE} {
228 ++yylineno;
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000229 yylval->assign(1, '\n');
alokp@chromium.orgd08bb0c2012-04-23 19:27:13 +0000230 return '\n';
231}
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000232
shannon.woods%transgaming.com@gtempaccount.combcde56f2013-04-13 03:32:12 +0000233\\{NEWLINE} { ++yylineno; }
234
alokp@chromium.org78a35192012-04-19 17:16:26 +0000235. {
alokp@chromium.org432d6fc2012-06-27 22:13:21 +0000236 yylval->assign(1, yytext[0]);
237 return pp::Token::PP_OTHER;
alokp@chromium.org78a35192012-04-19 17:16:26 +0000238}
239
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000240<*><<EOF>> {
alokp@chromium.org19d7aa62012-05-31 17:34:05 +0000241 // YY_USER_ACTION is not invoked for handling EOF.
242 // Set the location for EOF token manually.
243 pp::Input* input = &yyextra->input;
244 pp::Input::Location* scanLoc = &yyextra->scanLoc;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000245 yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0;
alokp@chromium.org19d7aa62012-05-31 17:34:05 +0000246 if (scanLoc->sIndex != sIndexMax)
247 {
248 // We can only reach here if there are empty strings at the
249 // end of the input.
250 scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000251 // FIXME: this is not 64-bit clean.
252 yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
alokp@chromium.org19d7aa62012-05-31 17:34:05 +0000253 }
254 yylloc->file = yyfileno;
255 yylloc->line = yylineno;
256 yylval->clear();
257
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000258 if (YY_START == COMMENT)
259 {
260 yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT,
261 pp::SourceLocation(yyfileno, yylineno),
262 "");
263 }
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000264 yyterminate();
265}
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000266
267%%
268
alokp@chromium.org3a01d1b2011-08-30 05:10:53 +0000269namespace pp {
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000270
alokp@chromium.orgc022c3a2012-07-09 15:56:42 +0000271// TODO(alokp): Maximum token length should ideally be specified by
272// the preprocessor client, i.e., the compiler.
shannonwoods@chromium.org8ddaf5c2013-05-30 00:13:08 +0000273const size_t Tokenizer::kMaxTokenLength = MAX_SYMBOL_NAME_LEN;
alokp@chromium.orgc022c3a2012-07-09 15:56:42 +0000274
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000275Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
alokp@chromium.org3a01d1b2011-08-30 05:10:53 +0000276{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000277 mContext.diagnostics = diagnostics;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000278}
279
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000280Tokenizer::~Tokenizer()
281{
282 destroyScanner();
283}
284
shannon.woods@transgaming.com8e02e352013-02-28 23:20:08 +0000285bool Tokenizer::init(size_t count, const char* const string[], const int length[])
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000286{
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000287 if ((count > 0) && (string == 0)) return false;
288
289 mContext.input = Input(count, string, length);
290 return initScanner();
291}
292
alokp@chromium.org46aa13d2012-06-15 15:40:27 +0000293void Tokenizer::setFileNumber(int file)
294{
295 // We use column number as file number.
296 // See macro yyfileno.
297 yyset_column(file, mHandle);
298}
299
300void Tokenizer::setLineNumber(int line)
301{
302 yyset_lineno(line, mHandle);
303}
304
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000305void Tokenizer::lex(Token* token)
306{
alokp@chromium.org5b6a68e2012-06-28 20:29:13 +0000307 token->type = yylex(&token->text, &token->location, mHandle);
alokp@chromium.orgc022c3a2012-07-09 15:56:42 +0000308 if (token->text.size() > kMaxTokenLength)
309 {
310 mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
311 token->location, token->text);
312 token->text.erase(kMaxTokenLength);
313 }
314
alokp@chromium.org7fc38dd2012-06-14 18:23:23 +0000315 token->flags = 0;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000316
alokp@chromium.org19d7aa62012-05-31 17:34:05 +0000317 token->setAtStartOfLine(mContext.lineStart);
318 mContext.lineStart = token->type == '\n';
319
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000320 token->setHasLeadingSpace(mContext.leadingSpace);
321 mContext.leadingSpace = false;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000322}
323
324bool Tokenizer::initScanner()
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000325{
alokp@chromium.org98eec912012-05-01 10:04:08 +0000326 if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000327 return false;
328
alokp@chromium.org98eec912012-05-01 10:04:08 +0000329 yyrestart(0, mHandle);
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000330 return true;
331}
332
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000333void Tokenizer::destroyScanner()
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000334{
alokp@chromium.org01fd4312012-03-30 21:33:30 +0000335 if (mHandle == NULL)
336 return;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000337
alokp@chromium.org01fd4312012-03-30 21:33:30 +0000338 yylex_destroy(mHandle);
339 mHandle = NULL;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000340}
341
342} // namespace pp
343