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
generate_keywords.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3#include <stdio.h>
4#include <string.h>
5#include <qbytearray.h>
6#include <qlist.h>
7
8struct Keyword
9{
10 const char *lexem;
11 const char *token;
12};
13
14static const Keyword pp_keywords[] = {
15 { "<", "PP_LANGLE" },
16 { ">", "PP_RANGLE" },
17 { "(", "PP_LPAREN"},
18 { ")", "PP_RPAREN"},
19 { ",", "PP_COMMA"},
20 { "\n", "PP_NEWLINE"},
21 { "#define", "PP_DEFINE"},
22 { "#if", "PP_IF"},
23 { "#undef", "PP_UNDEF"},
24 { "#ifdef", "PP_IFDEF"},
25 { "#ifndef", "PP_IFNDEF"},
26 { "#elif", "PP_ELIF"},
27 { "#else", "PP_ELSE"},
28 { "#endif", "PP_ENDIF"},
29 { "#include", "PP_INCLUDE"},
30 { "defined", "PP_DEFINED"},
31 { "+", "PP_PLUS" },
32 { "-", "PP_MINUS" },
33 { "*", "PP_STAR" },
34 { "/", "PP_SLASH" },
35 { "%", "PP_PERCENT" },
36 { "^", "PP_HAT" },
37 { "&", "PP_AND" },
38 { "bitand", "PP_AND" },
39 { "|", "PP_OR" },
40 { "bitor", "PP_OR" },
41 { "~", "PP_TILDE" },
42 { "compl", "PP_TILDE" },
43 { "!", "PP_NOT" },
44 { "not", "PP_NOT" },
45 { "<<", "PP_LTLT" },
46 { ">>", "PP_GTGT" },
47 { "==", "PP_EQEQ" },
48 { "!=", "PP_NE" },
49 { "not_eq", "PP_NE" },
50 { "<=", "PP_LE" },
51 { ">=", "PP_GE" },
52 { "&&", "PP_ANDAND" },
53 { "||", "PP_OROR" },
54 { "?", "PP_QUESTION" },
55 { ":", "PP_COLON" },
56 { "##", "PP_HASHHASH"},
57 { "%:%:", "PP_HASHHASH"},
58 { "#", "PP_HASH"},
59 { "\"", "PP_QUOTE"},
60 { "\'", "PP_SINGLEQUOTE"},
61 { " ", "PP_WHITESPACE" },
62 { "\t", "PP_WHITESPACE" },
63 { "//", "PP_CPP_COMMENT" },
64 { "/*", "PP_C_COMMENT" },
65 { "\\", "PP_BACKSLASH" },
66 { 0, "PP_NOTOKEN"}
67};
68
69static const Keyword keywords[] = {
70 { "<", "LANGLE" },
71 { ">", "RANGLE" },
72 { "(", "LPAREN" },
73 { ")", "RPAREN" },
74 { "...", "ELIPSIS" },
75 { ",", "COMMA" },
76 { "[", "LBRACK" },
77 { "]", "RBRACK" },
78 { "<:", "LBRACK" },
79 { ":>", "RBRACK" },
80 { "<::", "LANGLE_SCOPE" },
81 { "{", "LBRACE" },
82 { "<%", "LBRACE" },
83 { "}", "RBRACE" },
84 { "%>", "RBRACE" },
85 { "=", "EQ" },
86 { "::", "SCOPE" },
87 { ";", "SEMIC" },
88 { ":", "COLON" },
89 { ".*", "DOTSTAR" },
90 { "?", "QUESTION" },
91 { ".", "DOT" },
92 { "dynamic_cast", "DYNAMIC_CAST" },
93 { "static_cast", "STATIC_CAST" },
94 { "reinterpret_cast", "REINTERPRET_CAST" },
95 { "const_cast", "CONST_CAST" },
96 { "typeid", "TYPEID" },
97 { "this", "THIS" },
98 { "template", "TEMPLATE" },
99 { "throw", "THROW" },
100 { "try", "TRY" },
101 { "catch", "CATCH" },
102 { "typedef", "TYPEDEF" },
103 { "friend", "FRIEND" },
104 { "class", "CLASS" },
105 { "namespace", "NAMESPACE" },
106 { "enum", "ENUM" },
107 { "struct", "STRUCT" },
108 { "union", "UNION" },
109 { "virtual", "VIRTUAL" },
110 { "private", "PRIVATE" },
111 { "protected", "PROTECTED" },
112 { "public", "PUBLIC" },
113 { "export", "EXPORT" },
114 { "auto", "AUTO" },
115 { "register", "REGISTER" },
116 { "extern", "EXTERN" },
117 { "mutable", "MUTABLE" },
118 { "asm", "ASM" },
119 { "using", "USING" },
120 { "inline", "INLINE" },
121 { "explicit", "EXPLICIT" },
122 { "static", "STATIC" },
123 { "const", "CONST" },
124 { "volatile", "VOLATILE" },
125 { "operator", "OPERATOR" },
126 { "sizeof", "SIZEOF" },
127 { "new", "NEW" },
128 { "delete", "DELETE" },
129 { "+", "PLUS" },
130 { "-", "MINUS" },
131 { "*", "STAR" },
132 { "/", "SLASH" },
133 { "%", "PERCENT" },
134 { "^", "HAT" },
135 { "&", "AND" },
136 { "bitand", "AND" },
137 { "|", "OR" },
138 { "bitor", "OR" },
139 { "~", "TILDE" },
140 { "compl", "TILDE" },
141 { "!", "NOT" },
142 { "not", "NOT" },
143 { "+=", "PLUS_EQ" },
144 { "-=", "MINUS_EQ" },
145 { "*=", "STAR_EQ" },
146 { "/=", "SLASH_EQ" },
147 { "%=", "PERCENT_EQ" },
148 { "^=", "HAT_EQ" },
149 { "&=", "AND_EQ" },
150 { "|=", "OR_EQ" },
151 { "<<", "LTLT" },
152 { ">>", "GTGT" },
153 { ">>=", "GTGT_EQ" },
154 { "<<=", "LTLT_EQ" },
155 { "==", "EQEQ" },
156 { "!=", "NE" },
157 { "not_eq", "NE" },
158 { "<=", "LE" },
159 { ">=", "GE" },
160 { "&&", "ANDAND" },
161 { "||", "OROR" },
162 { "++", "INCR" },
163 { "--", "DECR" },
164 { ",", "COMMA" },
165 { "->*", "ARROW_STAR" },
166 { "->", "ARROW" },
167 { "char", "CHAR" },
168 { "wchar", "WCHAR" },
169 { "bool", "BOOL" },
170 { "short", "SHORT" },
171 { "int", "INT" },
172 { "long", "LONG" },
173 { "signed", "SIGNED" },
174 { "unsigned", "UNSIGNED" },
175 { "float", "FLOAT" },
176 { "double", "DOUBLE" },
177 { "void", "VOID" },
178 { "case", "CASE" },
179 { "default", "DEFAULT" },
180 { "if", "IF" },
181 { "else", "ELSE" },
182 { "switch", "SWITCH" },
183 { "while", "WHILE" },
184 { "do", "DO" },
185 { "for", "FOR" },
186 { "break", "BREAK" },
187 { "continue", "CONTINUE" },
188 { "goto", "GOTO" },
189 { "return", "RETURN" },
190 { "Q_OBJECT", "Q_OBJECT_TOKEN" },
191 { "Q_NAMESPACE", "Q_NAMESPACE_TOKEN" },
192 { "Q_NAMESPACE_EXPORT", "Q_NAMESPACE_EXPORT_TOKEN" },
193 { "Q_GADGET", "Q_GADGET_TOKEN" },
194 { "Q_GADGET_EXPORT", "Q_GADGET_EXPORT_TOKEN" },
195 { "Q_PROPERTY", "Q_PROPERTY_TOKEN" },
196 { "QT_ANONYMOUS_PROPERTY", "QT_ANONYMOUS_PROPERTY_TOKEN" },
197 { "Q_PLUGIN_METADATA", "Q_PLUGIN_METADATA_TOKEN" },
198 { "Q_ENUMS", "Q_ENUMS_TOKEN" },
199 { "Q_ENUM", "Q_ENUM_TOKEN" },
200 { "Q_ENUM_NS", "Q_ENUM_NS_TOKEN" },
201 { "Q_FLAGS", "Q_FLAGS_TOKEN" },
202 { "Q_FLAG", "Q_FLAG_TOKEN" },
203 { "Q_FLAG_NS", "Q_FLAG_NS_TOKEN" },
204 { "Q_DECLARE_FLAGS", "Q_DECLARE_FLAGS_TOKEN" },
205 { "Q_DECLARE_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
206 { "Q_DECLARE_METATYPE", "Q_DECLARE_METATYPE_TOKEN" },
207 { "Q_DECLARE_EXTENSION_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
208 { "Q_SETS", "Q_FLAGS_TOKEN" },
209 { "Q_CLASSINFO", "Q_CLASSINFO_TOKEN" },
210 { "Q_INTERFACES", "Q_INTERFACES_TOKEN" },
211 { "signals", "SIGNALS" },
212 { "slots", "SLOTS" },
213 { "Q_SIGNALS", "Q_SIGNALS_TOKEN" },
214 { "Q_SLOTS", "Q_SLOTS_TOKEN" },
215 { "Q_PRIVATE_SLOT", "Q_PRIVATE_SLOT_TOKEN" },
216 { "QT_MOC_COMPAT", "Q_MOC_COMPAT_TOKEN" },
217 { "Q_INVOKABLE", "Q_INVOKABLE_TOKEN" },
218 { "Q_SIGNAL", "Q_SIGNAL_TOKEN" },
219 { "Q_SLOT", "Q_SLOT_TOKEN" },
220 { "Q_SCRIPTABLE", "Q_SCRIPTABLE_TOKEN" },
221 { "Q_PRIVATE_PROPERTY", "Q_PRIVATE_PROPERTY_TOKEN" },
222 { "QT_ANONYMOUS_PRIVATE_PROPERTY", "QT_ANONYMOUS_PRIVATE_PROPERTY_TOKEN" },
223 { "Q_REVISION", "Q_REVISION_TOKEN" },
224 { "Q_MOC_INCLUDE", "Q_MOC_INCLUDE_TOKEN" },
225 { "\n", "NEWLINE" },
226 { "\"", "QUOTE" },
227 { "\'", "SINGLEQUOTE" },
228 { " ", "WHITESPACE" },
229 { "\t", "WHITESPACE" },
230 { "#", "HASH" },
231 { "##", "PP_HASHHASH" },
232 { "\\", "BACKSLASH" },
233 { "//", "CPP_COMMENT" },
234 { "/*", "C_COMMENT" },
235 { 0, "NOTOKEN"}
236};
237
238
239inline bool is_ident_start(char s)
240{
241 return ((s >= 'a' && s <= 'z')
242 || (s >= 'A' && s <= 'Z')
243 || s == '_' || s == '$'
244 );
245}
246
247inline bool is_ident_char(char s)
248{
249 return ((s >= 'a' && s <= 'z')
250 || (s >= 'A' && s <= 'Z')
251 || (s >= '0' && s <= '9')
252 || s == '_' || s == '$'
253 );
254}
255struct State
256{
257 State(const char* token):token(token), nextindex(0),
258 defchar(0), defnext(0), ident(0) {
259 memset( next, 0, sizeof(next));
260 }
262 int next[128];
264
267
268 const char *ident;
269
270 bool operator==(const State& o) const
271 {
272 return (token == o.token
273 && nextindex == o.nextindex
274 && defchar == o.defchar
275 && defnext == o.defnext
276 && ident == o.ident);
277 }
278};
279
280void newState(QList<State> &states, const char *token, const char *lexem, bool pre)
281{
282 const char *ident = nullptr;
283 if (is_ident_start(*lexem))
284 ident = pre?"PP_CHARACTER" : "CHARACTER";
285 else if (*lexem == '#')
286 ident = pre?"PP_HASH" : "HASH";
287
288 int state = 0;
289 while (*lexem) {
290 int next = states[state].next[(int)*lexem];
291 if (!next) {
292 const char *t = nullptr;
293 if (ident)
294 t = ident;
295 else
296 t = pre?"PP_INCOMPLETE":"INCOMPLETE";
297 next = states.size();
298 states += State(t);
299 states[state].next[(int)*lexem] = next;
300 states[next].ident = ident;
301 }
302 state = next;
303 ++lexem;
304 if (ident && !is_ident_char(*lexem))
305 ident = nullptr;
306 }
307 states[state].token = token;
308}
309
310void newState(QList<State> &states, const char *token, char lexem)
311{
312 int next = states[0].next[(int)lexem];
313 if (!next) {
314 next = states.size();
315 states += State(token);
316 states[0].next[(int)lexem] = next;
317 } else {
318 states[next].token = token;
319 }
320}
321
322
324{
325 int i,c;
326 bool pre = (keywords == pp_keywords);
327 QList<State> states;
328 states += State(pre?"PP_NOTOKEN":"NOTOKEN");
329
330 // identifiers
331 for (c = 'a'; c <= 'z'; ++c)
332 newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
333 for (c = 'A'; c <= 'Z'; ++c)
334 newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
335
336 newState(states, pre?"PP_CHARACTER":"CHARACTER", '_');
337 newState(states, pre?"PP_CHARACTER":"CHARACTER", '$');
338
339 // add digits
340 for (c = '0'; c <= '9'; ++c)
341 newState(states, pre?"PP_DIGIT":"DIGIT", c);
342
343 // keywords
344 for (i = 0; keywords[i].lexem; ++i)
345 newState(states, keywords[i].token, keywords[i].lexem, pre);
346
347 // some floats
348 for (c = '0'; c <= '9'; ++c)
349 newState(states, pre?"PP_FLOATING_LITERAL":"FLOATING_LITERAL",
350 QByteArray(".") + char(c), pre);
351
352 // simplify table with default transitions
353 int transindex = -1;
354 for (i = 0; i < states.size(); ++i) {
355 int n = 0;
356 int defchar = -1;
357 for (c = 0; c < 128; ++c)
358 if (states[i].next[c]) {
359 ++n;
360 defchar = c;
361 }
362 if (!n)
363 continue;
364 if (n == 1) {
365 states[i].defnext = states[i].next[defchar];
366 states[i].defchar = defchar;
367 continue;
368 }
369 states[i].nextindex = ++transindex;
370 }
371
372#if 1
373 // compress table
374 int j, k;
375 for (i = 0; i < states.size(); ++i) {
376 for (j = i + 1; j < states.size(); ++j) {
377 if ( states[i] == states[j] ) {
378 for (k = 0; k < states.size(); ++k) {
379 if (states[k].defnext == j)
380 states[k].defnext = i;
381 if (states[k].defnext > j)
382 --states[k].defnext;
383 for (c = 0; c < 128; ++c) {
384 if (states[k].next[c] == j)
385 states[k].next[c] = i;
386 if (states[k].next[c] > j)
387 --states[k].next[c];
388 }
389 }
390 states.removeAt(j);
391 --j;
392 }
393 }
394 }
395#endif
396 printf("static const short %skeyword_trans[][128] = {\n",
397 pre?"pp_":"");
398 for (i = 0; i < states.size(); ++i) {
399 if (i && !states[i].nextindex)
400 continue;
401 printf("%s {", i?",\n":"");
402 for (c = 0; c < 128; ++c)
403 printf("%s%s%d",
404 c?",":"",
405 (!c || c%16)?"":"\n ",
406 states[i].next[c]
407 );
408 printf("}");
409 }
410 printf("\n};\n\n");
411
412 printf("static const struct\n{\n"
413 " %sToken token;\n"
414 " short next;\n"
415 " char defchar;\n"
416 " short defnext;\n"
417 " %sToken ident;\n"
418 "} %skeywords[] = {\n",
419 pre ? "PP_":"",
420 pre ? "PP_":"",
421 pre ? "pp_":"");
422 for (i = 0; i < states.size(); ++i) {
423 printf("%s {%s, %d, %d, %d, %s}",
424 i?",\n":"",
425 states[i].token.data(),
426 states[i].nextindex,
427 states[i].defchar,
428 states[i].defnext,
429 states[i].ident?states[i].ident:(pre?"PP_NOTOKEN":"NOTOKEN"));
430 }
431 printf("\n};\n");
432}
433
434int main(int argc, char **)
435{
436 printf("// auto generated\n"
437 "// DO NOT EDIT.\n\n");
438 if ( argc > 1 )
440 else
442 return 0;
443}
\inmodule QtCore
Definition qbytearray.h:57
int main()
[0]
else opt state
[0]
static const Keyword keywords[]
bool is_ident_char(char s)
void makeTable(const Keyword keywords[])
bool is_ident_start(char s)
static const Keyword pp_keywords[]
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
short next
Definition keywords.cpp:445
short defnext
Definition keywords.cpp:447
Token token
Definition keywords.cpp:444
Token ident
Definition keywords.cpp:448
char defchar
Definition keywords.cpp:446
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
GLfloat n
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint * states
const char * lexem
const char * token
State(const char *token)
bool operator==(const State &o) const
QByteArray token
const char * ident
int next[128]