~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocessor.l

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
//
 
3
// Copyright 2002 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 scripts/run_code_generation.py
 
13
*/
 
14
 
 
15
%top{
 
16
// GENERATED FILE - DO NOT EDIT.
 
17
// Generated by generate_parser.py from preprocessor.l
 
18
//
 
19
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
 
20
// Use of this source code is governed by a BSD-style license that can be
 
21
// found in the LICENSE file.
 
22
//
 
23
// preprocessor.l:
 
24
//   Lexer for the OpenGL shading language preprocessor.
 
25
 
 
26
}
 
27
 
 
28
%{
 
29
#if defined(_MSC_VER)
 
30
#pragma warning(disable: 4005)
 
31
#endif
 
32
 
 
33
#include "compiler/preprocessor/Tokenizer.h"
 
34
 
 
35
#include "compiler/preprocessor/DiagnosticsBase.h"
 
36
#include "compiler/preprocessor/Token.h"
 
37
 
 
38
#if defined(__GNUC__)
 
39
// Triggered by the auto-generated yy_fatal_error function.
 
40
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
 
41
#elif defined(_MSC_VER)
 
42
#pragma warning(disable: 4244)
 
43
#endif
 
44
#if defined(__clang__)
 
45
// Flex uses `/*FALLTHROUGH*/` instead of dedicated statements.
 
46
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
 
47
#if defined(__APPLE__)
 
48
// Older clang versions don't have -Wextra-semi-stmt, and detecting Apple clang versions is
 
49
// difficult because they use different yet overlapping version numbers vs. regular clang.
 
50
#pragma clang diagnostic ignored "-Wunknown-warning-option"
 
51
#endif
 
52
// Flex isn't semi-colon clean.
 
53
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
 
54
#pragma clang diagnostic ignored "-Wunreachable-code"
 
55
#endif
 
56
 
 
57
// Workaround for flex using the register keyword, deprecated in C++11.
 
58
#ifdef __cplusplus
 
59
#if __cplusplus > 199711L
 
60
#define register
 
61
#endif
 
62
#endif
 
63
 
 
64
typedef std::string YYSTYPE;
 
65
typedef angle::pp::SourceLocation YYLTYPE;
 
66
 
 
67
// Use the unused yycolumn variable to track file (string) number.
 
68
#define yyfileno yycolumn
 
69
 
 
70
#define YY_USER_INIT                   \
 
71
    do {                               \
 
72
        yyfileno = 0;                  \
 
73
        yylineno = 1;                  \
 
74
        yyextra->leadingSpace = false; \
 
75
        yyextra->lineStart = true;     \
 
76
    } while(0);
 
77
 
 
78
#define YY_NO_INPUT
 
79
#define YY_USER_ACTION                                              \
 
80
    do                                                              \
 
81
    {                                                               \
 
82
        angle::pp::Input* input = &yyextra->input;                  \
 
83
        angle::pp::Input::Location* scanLoc = &yyextra->scanLoc;    \
 
84
        while ((scanLoc->sIndex < input->count()) &&                \
 
85
               (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
 
86
        {                                                           \
 
87
            scanLoc->cIndex -= input->length(scanLoc->sIndex++);    \
 
88
            ++yyfileno; yylineno = 1;                               \
 
89
        }                                                           \
 
90
        yylloc->file = yyfileno;                                    \
 
91
        yylloc->line = yylineno;                                    \
 
92
        scanLoc->cIndex += yyleng;                                  \
 
93
    } while(0);
 
94
 
 
95
#define YY_INPUT(buf, result, maxSize) \
 
96
    result = yyextra->input.read(buf, maxSize, &yylineno);
 
97
 
 
98
%}
 
99
 
 
100
%option noyywrap nounput never-interactive
 
101
%option reentrant bison-bridge bison-locations
 
102
%option prefix="pp"
 
103
%option extra-type="angle::pp::Tokenizer::Context*"
 
104
%x COMMENT
 
105
 
 
106
NEWLINE     \n|\r|\r\n
 
107
IDENTIFIER  [_a-zA-Z][_a-zA-Z0-9]*
 
108
PUNCTUATOR  [][<>(){}.+-/*%^|&~=!:;,?]
 
109
 
 
110
DECIMAL_CONSTANT      [1-9][0-9]*[uU]?
 
111
OCTAL_CONSTANT        0[0-7]*[uU]?
 
112
HEXADECIMAL_CONSTANT  0[xX][0-9a-fA-F]+[uU]?
 
113
 
 
114
DIGIT                [0-9]
 
115
EXPONENT_PART        [eE][+-]?{DIGIT}+
 
116
FRACTIONAL_CONSTANT  ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
 
117
 
 
118
%%
 
119
 
 
120
    /* Line comment */
 
121
"//"[^\r\n]*
 
122
 
 
123
    /* Block comment */
 
124
    /* Line breaks are just counted - not returned. */
 
125
    /* The comment is replaced by a single space. */
 
126
"/*" { BEGIN(COMMENT); }
 
127
<COMMENT>[^*\r\n]+
 
128
<COMMENT>"*"
 
129
<COMMENT>{NEWLINE} {
 
130
    if (yylineno == INT_MAX)
 
131
    {
 
132
        *yylval = "Integer overflow on line number";
 
133
        return angle::pp::Token::GOT_ERROR;
 
134
    }
 
135
    ++yylineno;
 
136
}
 
137
<COMMENT>"*/" {
 
138
    yyextra->leadingSpace = true;
 
139
    BEGIN(INITIAL);
 
140
}
 
141
 
 
142
# {
 
143
    // # is only valid at start of line for preprocessor directives.
 
144
    yylval->assign(1, yytext[0]);
 
145
    return yyextra->lineStart ? angle::pp::Token::PP_HASH : angle::pp::Token::PP_OTHER;
 
146
}
 
147
 
 
148
{IDENTIFIER} {
 
149
    yylval->assign(yytext, yyleng);
 
150
    return angle::pp::Token::IDENTIFIER;
 
151
}
 
152
 
 
153
({DECIMAL_CONSTANT}[uU]?)|({OCTAL_CONSTANT}[uU]?)|({HEXADECIMAL_CONSTANT}[uU]?) {
 
154
    yylval->assign(yytext, yyleng);
 
155
    return angle::pp::Token::CONST_INT;
 
156
}
 
157
 
 
158
({DIGIT}+{EXPONENT_PART}[fF]?)|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?[fF]?) {
 
159
    yylval->assign(yytext, yyleng);
 
160
    return angle::pp::Token::CONST_FLOAT;
 
161
}
 
162
 
 
163
    /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
 
164
    /* Rule to catch all invalid integers and floats. */
 
165
({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) {
 
166
    yylval->assign(yytext, yyleng);
 
167
    return angle::pp::Token::PP_NUMBER;
 
168
}
 
169
 
 
170
"++" {
 
171
    yylval->assign(yytext, yyleng);
 
172
    return angle::pp::Token::OP_INC;
 
173
}
 
174
"--" {
 
175
    yylval->assign(yytext, yyleng);
 
176
    return angle::pp::Token::OP_DEC;
 
177
}
 
178
"<<" {
 
179
    yylval->assign(yytext, yyleng);
 
180
    return angle::pp::Token::OP_LEFT;
 
181
}
 
182
">>" {
 
183
    yylval->assign(yytext, yyleng);
 
184
    return angle::pp::Token::OP_RIGHT;
 
185
}
 
186
"<=" {
 
187
    yylval->assign(yytext, yyleng);
 
188
    return angle::pp::Token::OP_LE;
 
189
}
 
190
">=" {
 
191
    yylval->assign(yytext, yyleng);
 
192
    return angle::pp::Token::OP_GE;
 
193
}
 
194
"==" {
 
195
    yylval->assign(yytext, yyleng);
 
196
    return angle::pp::Token::OP_EQ;
 
197
}
 
198
"!=" {
 
199
    yylval->assign(yytext, yyleng);
 
200
    return angle::pp::Token::OP_NE;
 
201
}
 
202
"&&" {
 
203
    yylval->assign(yytext, yyleng);
 
204
    return angle::pp::Token::OP_AND;
 
205
}
 
206
"^^" {
 
207
    yylval->assign(yytext, yyleng);
 
208
    return angle::pp::Token::OP_XOR;
 
209
}
 
210
"||" {
 
211
    yylval->assign(yytext, yyleng);
 
212
    return angle::pp::Token::OP_OR;
 
213
}
 
214
"+=" {
 
215
    yylval->assign(yytext, yyleng);
 
216
    return angle::pp::Token::OP_ADD_ASSIGN;
 
217
}
 
218
"-=" {
 
219
    yylval->assign(yytext, yyleng);
 
220
    return angle::pp::Token::OP_SUB_ASSIGN;
 
221
}
 
222
"*=" {
 
223
    yylval->assign(yytext, yyleng);
 
224
    return angle::pp::Token::OP_MUL_ASSIGN;
 
225
}
 
226
"/=" {
 
227
    yylval->assign(yytext, yyleng);
 
228
    return angle::pp::Token::OP_DIV_ASSIGN;
 
229
}
 
230
"%=" {
 
231
    yylval->assign(yytext, yyleng);
 
232
    return angle::pp::Token::OP_MOD_ASSIGN;
 
233
}
 
234
"<<=" {
 
235
    yylval->assign(yytext, yyleng);
 
236
    return angle::pp::Token::OP_LEFT_ASSIGN;
 
237
}
 
238
">>=" {
 
239
    yylval->assign(yytext, yyleng);
 
240
    return angle::pp::Token::OP_RIGHT_ASSIGN;
 
241
}
 
242
"&=" {
 
243
    yylval->assign(yytext, yyleng);
 
244
    return angle::pp::Token::OP_AND_ASSIGN;
 
245
}
 
246
"^=" {
 
247
    yylval->assign(yytext, yyleng);
 
248
    return angle::pp::Token::OP_XOR_ASSIGN;
 
249
}
 
250
"|=" {
 
251
    yylval->assign(yytext, yyleng);
 
252
    return angle::pp::Token::OP_OR_ASSIGN;
 
253
}
 
254
 
 
255
{PUNCTUATOR} {
 
256
    yylval->assign(1, yytext[0]);
 
257
    return yytext[0];
 
258
}
 
259
 
 
260
[ \t\v\f]+   { yyextra->leadingSpace = true; }
 
261
 
 
262
{NEWLINE} {
 
263
    if (yylineno == INT_MAX)
 
264
    {
 
265
        *yylval = "Integer overflow on line number";
 
266
        return angle::pp::Token::GOT_ERROR;
 
267
    }
 
268
    ++yylineno;
 
269
    yylval->assign(1, '\n');
 
270
    return '\n';
 
271
}
 
272
 
 
273
. {
 
274
    yylval->assign(1, yytext[0]);
 
275
    return angle::pp::Token::PP_OTHER;
 
276
}
 
277
 
 
278
<*><<EOF>> {
 
279
    // YY_USER_ACTION is not invoked for handling EOF.
 
280
    // Set the location for EOF token manually.
 
281
    angle::pp::Input* input = &yyextra->input;
 
282
    angle::pp::Input::Location* scanLoc = &yyextra->scanLoc;
 
283
    yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0;
 
284
    if (scanLoc->sIndex != sIndexMax)
 
285
    {
 
286
        // We can only reach here if there are empty strings at the
 
287
        // end of the input.
 
288
        scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
 
289
        // FIXME: this is not 64-bit clean.
 
290
        yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
 
291
    }
 
292
    yylloc->file = yyfileno;
 
293
    yylloc->line = yylineno;
 
294
    yylval->clear();
 
295
 
 
296
    // Line number overflows fake EOFs to exit early, check for this case.
 
297
    if (yylineno == INT_MAX) {
 
298
        yyextra->diagnostics->report(angle::pp::Diagnostics::PP_TOKENIZER_ERROR,
 
299
                angle::pp::SourceLocation(yyfileno, yylineno),
 
300
                "Integer overflow on line number");
 
301
    }
 
302
    else if (YY_START == COMMENT)
 
303
    {
 
304
        yyextra->diagnostics->report(angle::pp::Diagnostics::PP_EOF_IN_COMMENT,
 
305
                                     angle::pp::SourceLocation(yyfileno, yylineno),
 
306
                                     "EOF while in a comment");
 
307
    }
 
308
    yyterminate();
 
309
}
 
310
 
 
311
%%
 
312
 
 
313
namespace angle {
 
314
 
 
315
namespace pp {
 
316
 
 
317
Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256)
 
318
{
 
319
    mContext.diagnostics = diagnostics;
 
320
}
 
321
 
 
322
Tokenizer::~Tokenizer()
 
323
{
 
324
    destroyScanner();
 
325
}
 
326
 
 
327
bool Tokenizer::init(size_t count, const char * const string[], const int length[])
 
328
{
 
329
    if ((count > 0) && (string == 0))
 
330
        return false;
 
331
 
 
332
    mContext.input = Input(count, string, length);
 
333
    return initScanner();
 
334
}
 
335
 
 
336
void Tokenizer::setFileNumber(int file)
 
337
{
 
338
    // We use column number as file number.
 
339
    // See macro yyfileno.
 
340
    yyset_column(file, mHandle);
 
341
}
 
342
 
 
343
void Tokenizer::setLineNumber(int line)
 
344
{
 
345
    yyset_lineno(line, mHandle);
 
346
}
 
347
 
 
348
void Tokenizer::setMaxTokenSize(size_t maxTokenSize)
 
349
{
 
350
    mMaxTokenSize = maxTokenSize;
 
351
}
 
352
 
 
353
void Tokenizer::lex(Token *token)
 
354
{
 
355
    int tokenType = yylex(&token->text, &token->location, mHandle);
 
356
 
 
357
    if (tokenType == Token::GOT_ERROR)
 
358
    {
 
359
        mContext.diagnostics->report(Diagnostics::PP_TOKENIZER_ERROR, token->location, token->text);
 
360
        token->type = Token::LAST;
 
361
    }
 
362
    else
 
363
    {
 
364
        token->type = tokenType;
 
365
    }
 
366
 
 
367
    if (token->text.size() > mMaxTokenSize)
 
368
    {
 
369
        mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG,
 
370
                                     token->location, token->text);
 
371
        token->text.erase(mMaxTokenSize);
 
372
    }
 
373
 
 
374
    token->flags = 0;
 
375
 
 
376
    token->setAtStartOfLine(mContext.lineStart);
 
377
    mContext.lineStart = token->type == '\n';
 
378
 
 
379
    token->setHasLeadingSpace(mContext.leadingSpace);
 
380
    mContext.leadingSpace = false;
 
381
}
 
382
 
 
383
bool Tokenizer::initScanner()
 
384
{
 
385
    if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
 
386
        return false;
 
387
 
 
388
    yyrestart(0, mHandle);
 
389
    return true;
 
390
}
 
391
 
 
392
void Tokenizer::destroyScanner()
 
393
{
 
394
    if (mHandle == nullptr)
 
395
        return;
 
396
 
 
397
    yylex_destroy(mHandle);
 
398
    mHandle = nullptr;
 
399
}
 
400
 
 
401
}  // namespace pp
 
402
 
 
403
} // namespace angle
 
404