gfx/angle/src/compiler/preprocessor/Tokenizer.l

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial