blob: 689ae64b0af27441f258d8630357e9477111d5e6 [file] [log] [blame]
alokp@chromium.org4e4b8072011-08-07 05:36:04 +00001/*
2//
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.
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//
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.
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"
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000027
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000028#include "DiagnosticsBase.h"
alokp@chromium.orgd089d112012-04-13 17:05:12 +000029#include "Token.h"
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000030
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +000031#if defined(__GNUC__)
32// Triggered by the auto-generated yy_fatal_error function.
33#pragma GCC diagnostic ignored "-Wmissing-noreturn"
34#endif
35
alokp@chromium.org4b2a5222012-04-03 17:19:42 +000036typedef std::string YYSTYPE;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000037typedef pp::SourceLocation YYLTYPE;
alokp@chromium.org4b2a5222012-04-03 17:19:42 +000038
alokp@chromium.org98eec912012-05-01 10:04:08 +000039// Use the unused yycolumn variable to track file (string) number.
40#define yyfileno yycolumn
41
alokp@chromium.org04d7d222012-05-16 19:24:07 +000042#define YY_USER_INIT \
43 do { \
44 yyfileno = 0; \
45 yylineno = 1; \
46 yyextra->leadingSpace = false; \
47 yyextra->lineStart = true; \
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000048 } while(0);
alokp@chromium.orgb81c4012011-08-21 06:53:11 +000049
alokp@chromium.org19d7aa62012-05-31 17:34:05 +000050#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; \
alokp@chromium.org98eec912012-05-01 10:04:08 +000064 } while(0);
65
66#define YY_INPUT(buf, result, maxSize) \
alokp@chromium.org30a487c2012-05-02 17:30:46 +000067 result = yyextra->input.read(buf, maxSize);
alokp@chromium.org128d9192012-04-26 22:39:21 +000068
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000069%}
70
alokp@chromium.org98eec912012-05-01 10:04:08 +000071%option noyywrap nounput never-interactive
alokp@chromium.orgd08bb0c2012-04-23 19:27:13 +000072%option reentrant bison-bridge bison-locations
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000073%option prefix="pp"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000074%option extra-type="pp::Tokenizer::Context*"
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +000075%x COMMENT
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000076
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +000077NEWLINE \n|\r|\r\n
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000078IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
79PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?]
80
81DECIMAL_CONSTANT [1-9][0-9]*
82OCTAL_CONSTANT 0[0-7]*
83HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+
84
alokp@chromium.orgb81c4012011-08-21 06:53:11 +000085DIGIT [0-9]
86EXPONENT_PART [eE][+-]?{DIGIT}+
87FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
88
alokp@chromium.org4e4b8072011-08-07 05:36:04 +000089%%
90
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +000091 /* Line comment */
92"//"[^\r\n]*
93
94 /* Block comment */
alokp@chromium.orga11a6ab2012-04-27 10:00:38 +000095 /* Line breaks are just counted - not returned. */
96 /* The comment is replaced by a single space. */
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000097"/*" { BEGIN(COMMENT); }
alokp@chromium.orga11a6ab2012-04-27 10:00:38 +000098<COMMENT>[^*\r\n]+
99<COMMENT>"*"
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000100<COMMENT>{NEWLINE} { ++yylineno; }
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000101<COMMENT>"*/" {
102 yyextra->leadingSpace = true;
103 BEGIN(INITIAL);
104}
alokp@chromium.org85f2b2c2012-04-25 06:06:33 +0000105
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000106# {
107 // # is only valid at start of line for preprocessor directives.
alokp@chromium.org432d6fc2012-06-27 22:13:21 +0000108 yylval->assign(1, yytext[0]);
109 return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000110}
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000111
112{IDENTIFIER} {
alokp@chromium.org4b2a5222012-04-03 17:19:42 +0000113 yylval->assign(yytext, yyleng);
114 return pp::Token::IDENTIFIER;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000115}
116
117{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} {
alokp@chromium.org4b2a5222012-04-03 17:19:42 +0000118 yylval->assign(yytext, yyleng);
119 return pp::Token::CONST_INT;
alokp@chromium.orgb81c4012011-08-21 06:53:11 +0000120}
121
122({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) {
alokp@chromium.org4b2a5222012-04-03 17:19:42 +0000123 yylval->assign(yytext, yyleng);
124 return pp::Token::CONST_FLOAT;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000125}
126
alokp@chromium.org78a35192012-04-19 17:16:26 +0000127 /* 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.]*) {
alokp@chromium.org432d6fc2012-06-27 22:13:21 +0000130 yylval->assign(yytext, yyleng);
131 return pp::Token::PP_NUMBER;
alokp@chromium.org78a35192012-04-19 17:16:26 +0000132}
133
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000134"++" {
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}
alokp@chromium.org3f990c42012-04-03 19:50:35 +0000218
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000219{PUNCTUATOR} {
220 yylval->assign(1, yytext[0]);
221 return yytext[0];
222}
223
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000224[ \t\v\f]+ { yyextra->leadingSpace = true; }
alokp@chromium.orgd08bb0c2012-04-23 19:27:13 +0000225
226{NEWLINE} {
227 ++yylineno;
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000228 yylval->assign(1, '\n');
alokp@chromium.orgd08bb0c2012-04-23 19:27:13 +0000229 return '\n';
230}
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000231
alokp@chromium.org78a35192012-04-19 17:16:26 +0000232. {
alokp@chromium.org432d6fc2012-06-27 22:13:21 +0000233 yylval->assign(1, yytext[0]);
234 return pp::Token::PP_OTHER;
alokp@chromium.org78a35192012-04-19 17:16:26 +0000235}
236
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000237<*><<EOF>> {
alokp@chromium.org19d7aa62012-05-31 17:34:05 +0000238 // 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)
244 {
245 // We can only reach here if there are empty strings at the
246 // end of the input.
247 scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
248 yyfileno = sIndexMax; yylineno = 1;
249 }
250 yylloc->file = yyfileno;
251 yylloc->line = yylineno;
252 yylval->clear();
253
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000254 if (YY_START == COMMENT)
255 {
256 yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT,
257 pp::SourceLocation(yyfileno, yylineno),
258 "");
259 }
alokp@chromium.org07d921d2012-05-22 20:22:08 +0000260 yyterminate();
261}
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000262
263%%
264
alokp@chromium.org3a01d1b2011-08-30 05:10:53 +0000265namespace pp {
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000266
alokp@chromium.orgc022c3a2012-07-09 15:56:42 +0000267// TODO(alokp): Maximum token length should ideally be specified by
268// the preprocessor client, i.e., the compiler.
269const size_t Tokenizer::kMaxTokenLength = 256;
270
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000271Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
alokp@chromium.org3a01d1b2011-08-30 05:10:53 +0000272{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000273 mContext.diagnostics = diagnostics;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000274}
275
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000276Tokenizer::~Tokenizer()
277{
278 destroyScanner();
279}
280
281bool Tokenizer::init(int count, const char* const string[], const int length[])
282{
283 if (count < 0) return false;
284 if ((count > 0) && (string == 0)) return false;
285
286 mContext.input = Input(count, string, length);
287 return initScanner();
288}
289
alokp@chromium.org46aa13d2012-06-15 15:40:27 +0000290void Tokenizer::setFileNumber(int file)
291{
292 // We use column number as file number.
293 // See macro yyfileno.
294 yyset_column(file, mHandle);
295}
296
297void Tokenizer::setLineNumber(int line)
298{
299 yyset_lineno(line, mHandle);
300}
301
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000302void Tokenizer::lex(Token* token)
303{
alokp@chromium.org5b6a68e2012-06-28 20:29:13 +0000304 token->type = yylex(&token->text, &token->location, mHandle);
alokp@chromium.orgc022c3a2012-07-09 15:56:42 +0000305 if (token->text.size() > kMaxTokenLength)
306 {
307 mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
308 token->location, token->text);
309 token->text.erase(kMaxTokenLength);
310 }
311
alokp@chromium.org7fc38dd2012-06-14 18:23:23 +0000312 token->flags = 0;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000313
alokp@chromium.org19d7aa62012-05-31 17:34:05 +0000314 token->setAtStartOfLine(mContext.lineStart);
315 mContext.lineStart = token->type == '\n';
316
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000317 token->setHasLeadingSpace(mContext.leadingSpace);
318 mContext.leadingSpace = false;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000319}
320
321bool Tokenizer::initScanner()
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000322{
alokp@chromium.org98eec912012-05-01 10:04:08 +0000323 if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000324 return false;
325
alokp@chromium.org98eec912012-05-01 10:04:08 +0000326 yyrestart(0, mHandle);
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000327 return true;
328}
329
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000330void Tokenizer::destroyScanner()
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000331{
alokp@chromium.org01fd4312012-03-30 21:33:30 +0000332 if (mHandle == NULL)
333 return;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000334
alokp@chromium.org01fd4312012-03-30 21:33:30 +0000335 yylex_destroy(mHandle);
336 mHandle = NULL;
alokp@chromium.org4e4b8072011-08-07 05:36:04 +0000337}
338
339} // namespace pp
340