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