Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
glsllexer.cpp
Go to the documentation of this file.
1
// Copyright (C) 2021 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
6
#
include
"glslparsertable_p.h"
7
#
include
"glsllexer_p.h"
8
#
include
"glslparser_p.h"
9
#
include
"glslengine_p.h"
10
#
include
<
cctype
>
11
#
include
<
iostream
>
12
#
include
<
cstdio
>
13
14
QT_BEGIN_NAMESPACE
15
16
using
namespace
GLSL;
17
18
Lexer::Lexer(Engine *engine,
const
char
*source,
unsigned
size)
19
: _engine(engine),
20
_source(source),
21
_it(source),
22
_size(size),
23
_yychar(
'\n'
),
24
_lineno(0),
25
_state(0),
26
_variant(Variant_Mask & ~Variant_Reserved),
// everything except reserved
27
_scanKeywords(
true
),
28
_scanComments(
false
)
29
{
30
}
31
32
Lexer::~Lexer()
33
{
34
}
35
36
void
Lexer::yyinp()
37
{
38
_yychar = (
unsigned
char
) *_it++;
39
if
(_yychar ==
'\n'
)
40
++_lineno;
41
}
42
43
int
Lexer::yylex(Token *tk)
44
{
45
const
char
*pos =
nullptr
;
46
int
line = 0;
47
_yyval.ptr =
nullptr
;
48
const
int
kind = yylex_helper(&pos, &line);
49
tk->kind = kind;
50
tk->position = pos - _source;
51
tk->length = _it - pos - 1;
52
tk->line = line;
53
tk->ptr = _yyval.ptr;
54
return
kind;
55
}
56
57
enum
{
58
State_normal
,
59
State_comment
60
};
61
62
int
Lexer::yylex_helper(
const
char
**position,
int
*line)
63
{
64
using
namespace
GLSL;
65
again:
66
while
(std::isspace(_yychar))
67
yyinp();
68
69
*position = _it - 1;
70
*line = _lineno;
71
72
if
(_yychar == 0)
73
return
Parser::EOF_SYMBOL;
74
75
if
(_state == State_comment) {
76
while
(_yychar) {
77
if
(_yychar ==
'*'
) {
78
yyinp();
79
if
(_yychar ==
'/'
) {
80
yyinp();
81
_state = State_normal;
82
break
;
83
}
84
}
else
{
85
yyinp();
86
}
87
}
88
return
Parser::T_COMMENT;
89
}
90
91
const
int
ch = _yychar;
92
yyinp();
93
94
switch
(ch) {
95
case
'#'
:
96
for
(; _yychar; yyinp()) {
97
if
(_yychar ==
'\n'
)
98
break
;
99
}
100
goto
again;
101
102
// one of `!', `!='
103
case
'!'
:
104
if
(_yychar ==
'='
) {
105
yyinp();
106
return
Parser::T_NE_OP;
107
}
108
return
Parser::T_BANG;
109
110
// one of
111
// %
112
// %=
113
case
'%'
:
114
if
(_yychar ==
'='
) {
115
yyinp();
116
return
Parser::T_MOD_ASSIGN;
117
}
118
return
Parser::T_PERCENT;
119
120
// one of
121
// &
122
// &&
123
// &=
124
case
'&'
:
125
if
(_yychar ==
'='
) {
126
yyinp();
127
return
Parser::T_AND_ASSIGN;
128
}
else
if
(_yychar ==
'&'
) {
129
yyinp();
130
return
Parser::T_AND_OP;
131
}
132
return
Parser::T_AMPERSAND;
133
134
// (
135
case
'('
:
136
return
Parser::T_LEFT_PAREN;
137
138
// )
139
case
')'
:
140
return
Parser::T_RIGHT_PAREN;
141
142
// one of
143
// *
144
// *=
145
case
'*'
:
146
if
(_yychar ==
'='
) {
147
yyinp();
148
return
Parser::T_MUL_ASSIGN;
149
}
150
return
Parser::T_STAR;
151
152
// one of
153
// ++
154
// +=
155
// +
156
case
'+'
:
157
if
(_yychar ==
'='
) {
158
yyinp();
159
return
Parser::T_ADD_ASSIGN;
160
}
else
if
(_yychar ==
'+'
) {
161
yyinp();
162
return
Parser::T_INC_OP;
163
}
164
return
Parser::T_PLUS;
165
166
// ,
167
case
','
:
168
return
Parser::T_COMMA;
169
170
// one of
171
// -
172
// --
173
// -=
174
case
'-'
:
175
if
(_yychar ==
'='
) {
176
yyinp();
177
return
Parser::T_SUB_ASSIGN;
178
}
else
if
(_yychar ==
'-'
) {
179
yyinp();
180
return
Parser::T_DEC_OP;
181
}
182
return
Parser::T_DASH;
183
184
// one of
185
// .
186
// float constant
187
case
'.'
:
188
if
(std::isdigit(_yychar)) {
189
const
char
*word = _it - 2;
190
while
(std::isalnum(_yychar)) {
191
yyinp();
192
}
193
if
(_engine)
194
_yyval.string = _engine->number(word, _it - word - 1);
195
return
Parser::T_NUMBER;
196
}
197
return
Parser::T_DOT;
198
199
// one of
200
// /
201
// /=
202
// comment
203
case
'/'
:
204
if
(_yychar ==
'/'
) {
205
for
(; _yychar; yyinp()) {
206
if
(_yychar ==
'\n'
)
207
break
;
208
}
209
if
(_scanComments)
210
return
Parser::T_COMMENT;
211
goto
again;
212
}
else
if
(_yychar ==
'*'
) {
213
yyinp();
214
while
(_yychar) {
215
if
(_yychar ==
'*'
) {
216
yyinp();
217
if
(_yychar ==
'/'
) {
218
yyinp();
219
if
(_scanComments)
220
return
Parser::T_COMMENT;
221
goto
again;
222
}
223
}
else
{
224
yyinp();
225
}
226
}
227
if
(_scanComments) {
228
_state = State_comment;
229
return
Parser::T_COMMENT;
230
}
231
goto
again;
232
}
else
if
(_yychar ==
'='
) {
233
yyinp();
234
return
Parser::T_DIV_ASSIGN;
235
}
236
return
Parser::T_SLASH;
237
238
// :
239
case
':'
:
240
return
Parser::T_COLON;
241
242
// ;
243
case
';'
:
244
return
Parser::T_SEMICOLON;
245
246
// one of
247
// <
248
// <=
249
// <<
250
// <<=
251
case
'<'
:
252
if
(_yychar ==
'='
) {
253
yyinp();
254
return
Parser::T_LE_OP;
255
}
else
if
(_yychar ==
'<'
) {
256
yyinp();
257
if
(_yychar ==
'='
) {
258
yyinp();
259
return
Parser::T_LEFT_ASSIGN;
260
}
261
return
Parser::T_LEFT_OP;
262
}
263
return
Parser::T_LEFT_ANGLE;
264
265
// one of
266
// =
267
// ==
268
case
'='
:
269
if
(_yychar ==
'='
) {
270
yyinp();
271
return
Parser::T_EQ_OP;
272
}
273
return
Parser::T_EQUAL;
274
275
// one of
276
// >
277
// >=
278
// >>=
279
// >>
280
case
'>'
:
281
if
(_yychar ==
'='
) {
282
yyinp();
283
return
Parser::T_GE_OP;
284
}
else
if
(_yychar ==
'>'
) {
285
yyinp();
286
if
(_yychar ==
'='
) {
287
yyinp();
288
return
Parser::T_RIGHT_ASSIGN;
289
}
290
return
Parser::T_RIGHT_OP;
291
}
292
return
Parser::T_RIGHT_ANGLE;
293
294
// ?
295
case
'?'
:
296
return
Parser::T_QUESTION;
297
298
// [
299
case
'['
:
300
return
Parser::T_LEFT_BRACKET;
301
302
// ]
303
case
']'
:
304
return
Parser::T_RIGHT_BRACKET;
305
306
// one of
307
// ^
308
// ^=
309
case
'^'
:
310
if
(_yychar ==
'='
) {
311
yyinp();
312
return
Parser::T_XOR_ASSIGN;
313
}
else
if
(_yychar ==
'^'
) {
314
yyinp();
315
return
Parser::T_XOR_OP;
316
}
317
return
Parser::T_CARET;
318
319
// {
320
case
'{'
:
321
return
Parser::T_LEFT_BRACE;
322
323
// one of
324
// |
325
// |=
326
// ||
327
case
'|'
:
328
if
(_yychar ==
'='
) {
329
yyinp();
330
return
Parser::T_OR_ASSIGN;
331
}
else
if
(_yychar ==
'|'
) {
332
yyinp();
333
return
Parser::T_OR_OP;
334
}
335
return
Parser::T_VERTICAL_BAR;
336
337
// }
338
case
'}'
:
339
return
Parser::T_RIGHT_BRACE;
340
341
// ~
342
case
'~'
:
343
return
Parser::T_TILDE;
344
345
default
:
346
if
(std::isalpha(ch) || ch ==
'_'
) {
347
const
char
*word = _it - 2;
348
while
(std::isalnum(_yychar) || _yychar ==
'_'
) {
349
yyinp();
350
}
351
if
(_scanKeywords) {
352
const
int
k = findKeyword(word, _it - word - 1);
353
354
if
(k != Parser::T_IDENTIFIER)
355
return
k;
356
}
357
if
(_engine)
358
_yyval.string = _engine->identifier(word, _it - word - 1);
359
return
Parser::T_IDENTIFIER;
360
}
else
if
(std::isdigit(ch)) {
361
const
char
*word = _it - 2;
362
while
(std::isalnum(_yychar) || _yychar ==
'.'
) {
363
yyinp();
364
}
365
if
(_engine)
366
_yyval.string = _engine->number(word, _it - word - 1);
367
return
Parser::T_NUMBER;
368
}
369
370
}
// switch
371
372
return
Parser::T_ERROR;
373
}
374
375
int
Lexer::findKeyword(
const
char
*word,
int
length)
const
376
{
377
int
t = classify(word, length);
378
if
(!(t & Variant_Mask))
379
return
t;
380
if
((_variant & t & Variant_Mask) == 0) {
381
// Return a "reserved word" token if this keyword is not permitted
382
// in the current language variant so that the syntax highlighter
383
// can warn the user about the word.
384
if
(!_scanKeywords)
385
return
Parser::T_RESERVED;
386
}
387
return
t & ~Variant_Mask;
388
}
389
390
void
Lexer::warning(
int
line,
const
QString &message)
391
{
392
_engine->warning(line, message);
393
}
394
395
void
Lexer::error(
int
line,
const
QString &message)
396
{
397
_engine->error(line, message);
398
}
399
400
QT_END_NAMESPACE
State_comment
@ State_comment
Definition
glsllexer.cpp:59
State_normal
@ State_normal
Definition
glsllexer.cpp:58
qtquick3d
src
glslparser
glsllexer.cpp
Generated on
for Qt by
1.18.0