1
|
1 /****************************************************************************
|
|
2 **
|
|
3 ** Copyright (C) 1992-2008 Nokia. All rights reserved.
|
|
4 ** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
|
|
5 **
|
|
6 ** This file is part of Qt Jambi.
|
|
7 **
|
|
8 ** * Commercial Usage
|
|
9 * Licensees holding valid Qt Commercial licenses may use this file in
|
|
10 * accordance with the Qt Commercial License Agreement provided with the
|
|
11 * Software or, alternatively, in accordance with the terms contained in
|
|
12 * a written agreement between you and Nokia.
|
|
13 *
|
|
14 *
|
|
15 * GNU General Public License Usage
|
|
16 * Alternatively, this file may be used under the terms of the GNU
|
|
17 * General Public License versions 2.0 or 3.0 as published by the Free
|
|
18 * Software Foundation and appearing in the file LICENSE.GPL included in
|
|
19 * the packaging of this file. Please review the following information
|
|
20 * to ensure GNU General Public Licensing requirements will be met:
|
|
21 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
|
22 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special
|
|
23 * exception, Nokia gives you certain additional rights. These rights
|
|
24 * are described in the Nokia Qt GPL Exception version 1.2, included in
|
|
25 * the file GPL_EXCEPTION.txt in this package.
|
|
26 *
|
|
27 * Qt for Windows(R) Licensees
|
|
28 * As a special exception, Nokia, as the sole copyright holder for Qt
|
|
29 * Designer, grants users of the Qt/Eclipse Integration plug-in the
|
|
30 * right for the Qt/Eclipse Integration to link to functionality
|
|
31 * provided by Qt Designer and its related libraries.
|
|
32 *
|
|
33 *
|
|
34 * If you are unsure which license is appropriate for your use, please
|
|
35 * contact the sales department at qt-sales@nokia.com.
|
|
36
|
|
37 **
|
|
38 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
39 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
40 **
|
|
41 ****************************************************************************/
|
|
42
|
|
43 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
44
|
|
45
|
|
46 // c++ support
|
|
47 #include "parser.h"
|
|
48 #include "tokens.h"
|
|
49 #include "lexer.h"
|
|
50 #include "control.h"
|
|
51
|
|
52 #include <cstdlib>
|
|
53 #include <iostream>
|
|
54
|
|
55 #define ADVANCE(tk, descr) \
|
|
56 { \
|
|
57 if (token_stream.lookAhead() != tk) { \
|
|
58 tokenRequiredError(tk); \
|
|
59 return false; \
|
|
60 } \
|
|
61 token_stream.nextToken(); \
|
|
62 }
|
|
63
|
|
64 #define ADVANCE_NR(tk, descr) \
|
|
65 do { \
|
|
66 if (token_stream.lookAhead() != tk) { \
|
|
67 tokenRequiredError(tk); \
|
|
68 } \
|
|
69 else \
|
|
70 token_stream.nextToken(); \
|
|
71 } while (0)
|
|
72
|
|
73 #define CHECK(tk) \
|
|
74 do { \
|
|
75 if (token_stream.lookAhead() != tk) { \
|
|
76 return false; \
|
|
77 } \
|
|
78 token_stream.nextToken(); \
|
|
79 } while (0)
|
|
80
|
|
81 #define UPDATE_POS(_node, start, end) \
|
|
82 do { \
|
|
83 (_node)->start_token = start; \
|
|
84 (_node)->end_token = end; \
|
|
85 } while (0)
|
|
86
|
|
87 Parser::Parser(Control *c)
|
|
88 : _M_location(token_stream, location_table, line_table),
|
|
89 control(c),
|
|
90 lexer(_M_location, control)
|
|
91 {
|
|
92 _M_block_errors = false;
|
|
93 }
|
|
94
|
|
95 Parser::~Parser()
|
|
96 {
|
|
97 }
|
|
98
|
|
99 void Parser::advance()
|
|
100 {
|
|
101 token_stream.nextToken();
|
|
102 }
|
|
103
|
|
104 TranslationUnitAST *Parser::parse(const char *contents,
|
|
105 std::size_t size, pool *p)
|
|
106 {
|
|
107 _M_block_errors = false;
|
|
108 _M_pool = p;
|
|
109 lexer.tokenize(contents, size);
|
|
110 token_stream.nextToken(); // skip the first token
|
|
111
|
|
112 Lexer *oldLexer = control->changeLexer (&lexer);
|
|
113 Parser *oldParser = control->changeParser (this);
|
|
114
|
|
115 TranslationUnitAST *ast = 0;
|
|
116 parseTranslationUnit(ast);
|
|
117
|
|
118 control->changeLexer (oldLexer);
|
|
119 control->changeParser (oldParser);
|
|
120
|
|
121 return ast;
|
|
122 }
|
|
123
|
|
124 bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node)
|
|
125 {
|
|
126 if (token_stream.lookAhead() != Token_identifier)
|
|
127 return false;
|
|
128
|
|
129 std::size_t start = token_stream.cursor();
|
|
130
|
|
131 const NameSymbol *name_symbol = token_stream.symbol(token_stream.cursor());
|
|
132 QString name = name_symbol->as_string();
|
|
133 if (name != QLatin1String("__declspec"))
|
|
134 return false;
|
|
135 std::size_t specifier = token_stream.cursor();
|
|
136
|
|
137 token_stream.nextToken();
|
|
138 if (token_stream.lookAhead() != '(')
|
|
139 return false;
|
|
140
|
|
141 token_stream.nextToken();
|
|
142 if (token_stream.lookAhead() != Token_identifier)
|
|
143 return false;
|
|
144 std::size_t modifier = token_stream.cursor();
|
|
145
|
|
146 token_stream.nextToken();
|
|
147 if (token_stream.lookAhead() != ')')
|
|
148 return false;
|
|
149
|
|
150 token_stream.nextToken();
|
|
151
|
|
152 node = CreateNode<WinDeclSpecAST>(_M_pool);
|
|
153 node->specifier = specifier;
|
|
154 node->modifier = modifier;
|
|
155
|
|
156 UPDATE_POS(node, start, token_stream.cursor());
|
|
157
|
|
158 return true;
|
|
159 }
|
|
160
|
|
161 void Parser::tokenRequiredError(int token)
|
|
162 {
|
|
163 QString err;
|
|
164
|
|
165 err += "expected token ";
|
|
166 err += "``";
|
|
167 err += token_name(token);
|
|
168 err += "'' found ``";
|
|
169 err += token_name(token_stream.lookAhead());
|
|
170 err += "''";
|
|
171
|
|
172 reportError(err);
|
|
173 }
|
|
174
|
|
175 void Parser::syntaxError()
|
|
176 {
|
|
177 QString err;
|
|
178
|
|
179 err += "unexpected token ";
|
|
180 err += "``";
|
|
181 err += token_name(token_stream.lookAhead());
|
|
182 err += "''";
|
|
183
|
|
184 reportError(err);
|
|
185 }
|
|
186
|
|
187 void Parser::reportError(const QString& msg)
|
|
188 {
|
|
189 if (!_M_block_errors)
|
|
190 {
|
|
191 int line, column;
|
|
192 QString fileName;
|
|
193
|
|
194 std::size_t tok = token_stream.cursor();
|
|
195 location().positionAt(token_stream.position(tok),
|
|
196 &line, &column, &fileName);
|
|
197
|
|
198 Control::ErrorMessage errmsg;
|
|
199 errmsg.setLine(line + 1);
|
|
200 errmsg.setColumn(column);
|
|
201 errmsg.setFileName(fileName);
|
|
202 errmsg.setMessage(QLatin1String("** PARSER ERROR ") + msg);
|
|
203 control->reportError(errmsg);
|
|
204 }
|
|
205 }
|
|
206
|
|
207 bool Parser::skipUntil(int token)
|
|
208 {
|
|
209 while (token_stream.lookAhead())
|
|
210 {
|
|
211 if (token_stream.lookAhead() == token)
|
|
212 return true;
|
|
213
|
|
214 token_stream.nextToken();
|
|
215 }
|
|
216
|
|
217 return false;
|
|
218 }
|
|
219
|
|
220 bool Parser::skipUntilDeclaration()
|
|
221 {
|
|
222 while (token_stream.lookAhead())
|
|
223 {
|
|
224
|
|
225 switch(token_stream.lookAhead())
|
|
226 {
|
|
227 case ';':
|
|
228 case '~':
|
|
229 case Token_scope:
|
|
230 case Token_identifier:
|
|
231 case Token_operator:
|
|
232 case Token_char:
|
|
233 case Token_wchar_t:
|
|
234 case Token_bool:
|
|
235 case Token_short:
|
|
236 case Token_int:
|
|
237 case Token_long:
|
|
238 case Token_signed:
|
|
239 case Token_unsigned:
|
|
240 case Token_float:
|
|
241 case Token_double:
|
|
242 case Token_void:
|
|
243 case Token_extern:
|
|
244 case Token_namespace:
|
|
245 case Token_using:
|
|
246 case Token_typedef:
|
|
247 case Token_asm:
|
|
248 case Token_template:
|
|
249 case Token_export:
|
|
250
|
|
251 case Token_const: // cv
|
|
252 case Token_volatile: // cv
|
|
253
|
|
254 case Token_public:
|
|
255 case Token_protected:
|
|
256 case Token_private:
|
|
257 case Token_signals: // Qt
|
|
258 case Token_slots: // Qt
|
|
259 return true;
|
|
260
|
|
261 default:
|
|
262 token_stream.nextToken();
|
|
263 }
|
|
264 }
|
|
265
|
|
266 return false;
|
|
267 }
|
|
268
|
|
269 bool Parser::skipUntilStatement()
|
|
270 {
|
|
271 while (token_stream.lookAhead())
|
|
272 {
|
|
273 switch(token_stream.lookAhead())
|
|
274 {
|
|
275 case ';':
|
|
276 case '{':
|
|
277 case '}':
|
|
278 case Token_const:
|
|
279 case Token_volatile:
|
|
280 case Token_identifier:
|
|
281 case Token_case:
|
|
282 case Token_default:
|
|
283 case Token_if:
|
|
284 case Token_switch:
|
|
285 case Token_while:
|
|
286 case Token_do:
|
|
287 case Token_for:
|
|
288 case Token_break:
|
|
289 case Token_continue:
|
|
290 case Token_return:
|
|
291 case Token_goto:
|
|
292 case Token_try:
|
|
293 case Token_catch:
|
|
294 case Token_throw:
|
|
295 case Token_char:
|
|
296 case Token_wchar_t:
|
|
297 case Token_bool:
|
|
298 case Token_short:
|
|
299 case Token_int:
|
|
300 case Token_long:
|
|
301 case Token_signed:
|
|
302 case Token_unsigned:
|
|
303 case Token_float:
|
|
304 case Token_double:
|
|
305 case Token_void:
|
|
306 case Token_class:
|
|
307 case Token_struct:
|
|
308 case Token_union:
|
|
309 case Token_enum:
|
|
310 case Token_scope:
|
|
311 case Token_template:
|
|
312 case Token_using:
|
|
313 return true;
|
|
314
|
|
315 default:
|
|
316 token_stream.nextToken();
|
|
317 }
|
|
318 }
|
|
319
|
|
320 return false;
|
|
321 }
|
|
322
|
|
323 bool Parser::skip(int l, int r)
|
|
324 {
|
|
325 int count = 0;
|
|
326 while (token_stream.lookAhead())
|
|
327 {
|
|
328 int tk = token_stream.lookAhead();
|
|
329
|
|
330 if (tk == l)
|
|
331 ++count;
|
|
332 else if (tk == r)
|
|
333 --count;
|
|
334 else if (l != '{' && (tk == '{' || tk == '}' || tk == ';'))
|
|
335 return false;
|
|
336
|
|
337 if (count == 0)
|
|
338 return true;
|
|
339
|
|
340 token_stream.nextToken();
|
|
341 }
|
|
342
|
|
343 return false;
|
|
344 }
|
|
345
|
|
346 bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
|
|
347 {
|
|
348 std::size_t start = token_stream.cursor();
|
|
349
|
|
350 WinDeclSpecAST *winDeclSpec = 0;
|
|
351 parseWinDeclSpec(winDeclSpec);
|
|
352
|
|
353 NameAST *ast = CreateNode<NameAST>(_M_pool);
|
|
354
|
|
355 if (token_stream.lookAhead() == Token_scope)
|
|
356 {
|
|
357 ast->global = true;
|
|
358 token_stream.nextToken();
|
|
359 }
|
|
360
|
|
361 std::size_t idx = token_stream.cursor();
|
|
362
|
|
363 while (true)
|
|
364 {
|
|
365 UnqualifiedNameAST *n = 0;
|
|
366 if (!parseUnqualifiedName(n))
|
|
367 return false;
|
|
368
|
|
369 if (token_stream.lookAhead() == Token_scope)
|
|
370 {
|
|
371 token_stream.nextToken();
|
|
372
|
|
373 ast->qualified_names
|
|
374 = snoc(ast->qualified_names, n, _M_pool);
|
|
375
|
|
376 if (token_stream.lookAhead() == Token_template)
|
|
377 {
|
|
378 /// skip optional template #### @todo CHECK
|
|
379 token_stream.nextToken();
|
|
380 }
|
|
381 }
|
|
382 else
|
|
383 {
|
|
384 Q_ASSERT(n != 0);
|
|
385 if (!acceptTemplateId)
|
|
386 {
|
|
387 token_stream.rewind((int) n->start_token);
|
|
388 parseUnqualifiedName(n, false);
|
|
389 }
|
|
390
|
|
391 ast->unqualified_name = n;
|
|
392 break;
|
|
393 }
|
|
394 }
|
|
395
|
|
396 if (idx == token_stream.cursor())
|
|
397 return false;
|
|
398
|
|
399 UPDATE_POS(ast, start, token_stream.cursor());
|
|
400 node = ast;
|
|
401
|
|
402 return true;
|
|
403 }
|
|
404
|
|
405 bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
|
|
406 {
|
|
407 std::size_t start = token_stream.cursor();
|
|
408 TranslationUnitAST *ast = CreateNode<TranslationUnitAST>(_M_pool);
|
|
409
|
|
410 while (token_stream.lookAhead())
|
|
411 {
|
|
412 std::size_t startDecl = token_stream.cursor();
|
|
413
|
|
414 DeclarationAST *declaration = 0;
|
|
415 if (parseDeclaration(declaration))
|
|
416 {
|
|
417 ast->declarations =
|
|
418 snoc(ast->declarations, declaration, _M_pool);
|
|
419 }
|
|
420 else
|
|
421 {
|
|
422 // error recovery
|
|
423 if (startDecl == token_stream.cursor())
|
|
424 {
|
|
425 // skip at least one token
|
|
426 token_stream.nextToken();
|
|
427 }
|
|
428
|
|
429 skipUntilDeclaration();
|
|
430 }
|
|
431 }
|
|
432
|
|
433 UPDATE_POS(ast, start, token_stream.cursor());
|
|
434 node = ast;
|
|
435
|
|
436 return true;
|
|
437 }
|
|
438
|
|
439 bool Parser::parseDeclaration(DeclarationAST *&node)
|
|
440 {
|
|
441 std::size_t start = token_stream.cursor();
|
|
442
|
|
443 switch(token_stream.lookAhead())
|
|
444 {
|
|
445 case ';':
|
|
446 token_stream.nextToken();
|
|
447 return true;
|
|
448
|
|
449 case Token_extern:
|
|
450 return parseLinkageSpecification(node);
|
|
451
|
|
452 case Token_namespace:
|
|
453 return parseNamespace(node);
|
|
454
|
|
455 case Token_using:
|
|
456 return parseUsing(node);
|
|
457
|
|
458 case Token_typedef:
|
|
459 return parseTypedef(node);
|
|
460
|
|
461 case Token_asm:
|
|
462 return parseAsmDefinition(node);
|
|
463
|
|
464 case Token_Q_ENUMS:
|
|
465 return parseQ_ENUMS(node);
|
|
466
|
|
467 case Token_template:
|
|
468 case Token_export:
|
|
469 return parseTemplateDeclaration(node);
|
|
470
|
|
471 default:
|
|
472 {
|
|
473 const ListNode<std::size_t> *cv = 0;
|
|
474 parseCvQualify(cv);
|
|
475
|
|
476 const ListNode<std::size_t> *storageSpec = 0;
|
|
477 parseStorageClassSpecifier(storageSpec);
|
|
478
|
|
479 parseCvQualify(cv);
|
|
480
|
|
481 TypeSpecifierAST *spec = 0;
|
|
482 if (parseEnumSpecifier(spec)
|
|
483 || parseClassSpecifier(spec)
|
|
484 || parseForwardDeclarationSpecifier(spec))
|
|
485 {
|
|
486 parseCvQualify(cv);
|
|
487
|
|
488 spec->cv = cv;
|
|
489
|
|
490 const ListNode<InitDeclaratorAST*> *declarators = 0;
|
|
491 parseInitDeclaratorList(declarators);
|
|
492 ADVANCE(';', ";");
|
|
493
|
|
494 SimpleDeclarationAST *ast =
|
|
495 CreateNode<SimpleDeclarationAST>(_M_pool);
|
|
496
|
|
497 ast->storage_specifiers = storageSpec;
|
|
498 ast->type_specifier = spec;
|
|
499 ast->init_declarators = declarators;
|
|
500 UPDATE_POS(ast, start, token_stream.cursor());
|
|
501 node = ast;
|
|
502
|
|
503 return true;
|
|
504 }
|
|
505 }
|
|
506 } // end switch
|
|
507
|
|
508 token_stream.rewind((int) start);
|
|
509 return parseDeclarationInternal(node);
|
|
510 }
|
|
511
|
|
512 bool Parser::parseLinkageSpecification(DeclarationAST *&node)
|
|
513 {
|
|
514 std::size_t start = token_stream.cursor();
|
|
515
|
|
516 CHECK(Token_extern);
|
|
517
|
|
518 LinkageSpecificationAST *ast = CreateNode<LinkageSpecificationAST>(_M_pool);
|
|
519
|
|
520 if (token_stream.lookAhead() == Token_string_literal)
|
|
521 {
|
|
522 ast->extern_type = token_stream.cursor();
|
|
523 token_stream.nextToken();
|
|
524 }
|
|
525
|
|
526 if (token_stream.lookAhead() == '{')
|
|
527 {
|
|
528 parseLinkageBody(ast->linkage_body);
|
|
529 }
|
|
530 else if (!parseDeclaration(ast->declaration))
|
|
531 {
|
|
532 reportError(("Declaration syntax error"));
|
|
533 }
|
|
534
|
|
535 UPDATE_POS(ast, start, token_stream.cursor());
|
|
536 node = ast;
|
|
537
|
|
538 return true;
|
|
539 }
|
|
540
|
|
541 bool Parser::parseLinkageBody(LinkageBodyAST *&node)
|
|
542 {
|
|
543 std::size_t start = token_stream.cursor();
|
|
544
|
|
545 CHECK('{');
|
|
546
|
|
547 LinkageBodyAST *ast = CreateNode<LinkageBodyAST>(_M_pool);
|
|
548
|
|
549 while (token_stream.lookAhead())
|
|
550 {
|
|
551 int tk = token_stream.lookAhead();
|
|
552
|
|
553 if (tk == '}')
|
|
554 break;
|
|
555
|
|
556 std::size_t startDecl = token_stream.cursor();
|
|
557
|
|
558 DeclarationAST *declaration = 0;
|
|
559 if (parseDeclaration(declaration))
|
|
560 {
|
|
561 ast->declarations = snoc(ast->declarations, declaration, _M_pool);
|
|
562 }
|
|
563 else
|
|
564 {
|
|
565 // error recovery
|
|
566 if (startDecl == token_stream.cursor())
|
|
567 {
|
|
568 // skip at least one token
|
|
569 token_stream.nextToken();
|
|
570 }
|
|
571
|
|
572 skipUntilDeclaration();
|
|
573 }
|
|
574 }
|
|
575
|
|
576 if (token_stream.lookAhead() != '}')
|
|
577 reportError(("} expected"));
|
|
578 else
|
|
579 token_stream.nextToken();
|
|
580
|
|
581 UPDATE_POS(ast, start, token_stream.cursor());
|
|
582 node = ast;
|
|
583
|
|
584 return true;
|
|
585 }
|
|
586
|
|
587 bool Parser::parseNamespace(DeclarationAST *&node)
|
|
588 {
|
|
589 std::size_t start = token_stream.cursor();
|
|
590
|
|
591 CHECK(Token_namespace);
|
|
592
|
|
593 std::size_t namespace_name = 0;
|
|
594 if (token_stream.lookAhead() == Token_identifier)
|
|
595 {
|
|
596 namespace_name = token_stream.cursor();
|
|
597 token_stream.nextToken();
|
|
598 }
|
|
599
|
|
600 if (token_stream.lookAhead() == '=')
|
|
601 {
|
|
602 // namespace alias
|
|
603 token_stream.nextToken();
|
|
604
|
|
605 NameAST *name = 0;
|
|
606 if (parseName(name))
|
|
607 {
|
|
608 ADVANCE(';', ";");
|
|
609
|
|
610 NamespaceAliasDefinitionAST *ast
|
|
611 = CreateNode<NamespaceAliasDefinitionAST>(_M_pool);
|
|
612 ast->namespace_name = namespace_name;
|
|
613 ast->alias_name = name;
|
|
614 UPDATE_POS(ast, start, token_stream.cursor());
|
|
615 node = ast;
|
|
616 return true;
|
|
617 }
|
|
618 else
|
|
619 {
|
|
620 reportError(("namespace expected"));
|
|
621 return false;
|
|
622 }
|
|
623 }
|
|
624 else if (token_stream.lookAhead() != '{')
|
|
625 {
|
|
626 reportError(("{ expected"));
|
|
627 return false;
|
|
628 }
|
|
629
|
|
630 NamespaceAST *ast = CreateNode<NamespaceAST>(_M_pool);
|
|
631 ast->namespace_name = namespace_name;
|
|
632 parseLinkageBody(ast->linkage_body);
|
|
633
|
|
634 UPDATE_POS(ast, start, token_stream.cursor());
|
|
635 node = ast;
|
|
636
|
|
637 return true;
|
|
638 }
|
|
639
|
|
640 bool Parser::parseUsing(DeclarationAST *&node)
|
|
641 {
|
|
642 std::size_t start = token_stream.cursor();
|
|
643
|
|
644 CHECK(Token_using);
|
|
645
|
|
646 if (token_stream.lookAhead() == Token_namespace)
|
|
647 return parseUsingDirective(node);
|
|
648
|
|
649 UsingAST *ast = CreateNode<UsingAST>(_M_pool);
|
|
650
|
|
651 if (token_stream.lookAhead() == Token_typename)
|
|
652 {
|
|
653 ast->type_name = token_stream.cursor();
|
|
654 token_stream.nextToken();
|
|
655 }
|
|
656
|
|
657 if (!parseName(ast->name))
|
|
658 return false;
|
|
659
|
|
660 ADVANCE(';', ";");
|
|
661
|
|
662 UPDATE_POS(ast, start, token_stream.cursor());
|
|
663 node = ast;
|
|
664
|
|
665 return true;
|
|
666 }
|
|
667
|
|
668 bool Parser::parseUsingDirective(DeclarationAST *&node)
|
|
669 {
|
|
670 std::size_t start = token_stream.cursor();
|
|
671
|
|
672 CHECK(Token_namespace);
|
|
673
|
|
674 NameAST *name = 0;
|
|
675 if (!parseName(name))
|
|
676 {
|
|
677 reportError(("Namespace name expected"));
|
|
678 return false;
|
|
679 }
|
|
680
|
|
681 ADVANCE(';', ";");
|
|
682
|
|
683 UsingDirectiveAST *ast = CreateNode<UsingDirectiveAST>(_M_pool);
|
|
684 ast->name = name;
|
|
685 UPDATE_POS(ast, start, token_stream.cursor());
|
|
686 node = ast;
|
|
687
|
|
688 return true;
|
|
689 }
|
|
690
|
|
691
|
|
692 bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node)
|
|
693 {
|
|
694 std::size_t start = token_stream.cursor();
|
|
695
|
|
696 CHECK(Token_operator);
|
|
697
|
|
698 OperatorFunctionIdAST *ast = CreateNode<OperatorFunctionIdAST>(_M_pool);
|
|
699
|
|
700 if (!parseOperator(ast->op))
|
|
701 {
|
|
702 ast->op = 0;
|
|
703
|
|
704 // parse cast operator
|
|
705 const ListNode<std::size_t> *cv = 0;
|
|
706 parseCvQualify(cv);
|
|
707
|
|
708 if (!parseSimpleTypeSpecifier(ast->type_specifier))
|
|
709 {
|
|
710 syntaxError();
|
|
711 return false;
|
|
712 }
|
|
713
|
|
714 parseCvQualify(cv);
|
|
715 ast->type_specifier->cv = cv;
|
|
716
|
|
717 PtrOperatorAST *ptr_op = 0;
|
|
718 while (parsePtrOperator(ptr_op))
|
|
719 ast->ptr_ops = snoc(ast->ptr_ops, ptr_op, _M_pool);
|
|
720 }
|
|
721
|
|
722 UPDATE_POS(ast, start, token_stream.cursor());
|
|
723 node = ast;
|
|
724 return true;
|
|
725 }
|
|
726
|
|
727 bool Parser::parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&node,
|
|
728 bool reportError)
|
|
729 {
|
|
730 TemplateArgumentAST *templArg = 0;
|
|
731 if (!parseTemplateArgument(templArg))
|
|
732 return false;
|
|
733
|
|
734 node = snoc(node, templArg, _M_pool);
|
|
735
|
|
736 while (token_stream.lookAhead() == ',')
|
|
737 {
|
|
738 token_stream.nextToken();
|
|
739
|
|
740 if (!parseTemplateArgument(templArg))
|
|
741 {
|
|
742 if (reportError)
|
|
743 {
|
|
744 syntaxError();
|
|
745 break;
|
|
746 }
|
|
747
|
|
748 node = 0;
|
|
749 return false;
|
|
750 }
|
|
751
|
|
752 node = snoc(node, templArg, _M_pool);
|
|
753 }
|
|
754
|
|
755 return true;
|
|
756 }
|
|
757
|
|
758 bool Parser::parseTypedef(DeclarationAST *&node)
|
|
759 {
|
|
760 std::size_t start = token_stream.cursor();
|
|
761
|
|
762 CHECK(Token_typedef);
|
|
763
|
|
764 TypeSpecifierAST *spec = 0;
|
|
765 if (!parseTypeSpecifierOrClassSpec(spec))
|
|
766 {
|
|
767 reportError(("Need a type specifier to declare"));
|
|
768 return false;
|
|
769 }
|
|
770
|
|
771 const ListNode<InitDeclaratorAST*> *declarators = 0;
|
|
772 if (!parseInitDeclaratorList(declarators))
|
|
773 {
|
|
774 //reportError(("Need an identifier to declare"));
|
|
775 //return false;
|
|
776 }
|
|
777
|
|
778 ADVANCE(';', ";");
|
|
779
|
|
780 TypedefAST *ast = CreateNode<TypedefAST>(_M_pool);
|
|
781 ast->type_specifier = spec;
|
|
782 ast->init_declarators = declarators;
|
|
783
|
|
784 UPDATE_POS(ast, start, token_stream.cursor());
|
|
785 node = ast;
|
|
786
|
|
787 return true;
|
|
788 }
|
|
789
|
|
790 bool Parser::parseAsmDefinition(DeclarationAST *&node)
|
|
791 {
|
|
792 std::size_t start = token_stream.cursor();
|
|
793
|
|
794 ADVANCE(Token_asm, "asm");
|
|
795
|
|
796 const ListNode<std::size_t> *cv = 0;
|
|
797 parseCvQualify(cv);
|
|
798
|
|
799 #if defined(__GNUC__)
|
|
800 #warning "implement me"
|
|
801 #endif
|
|
802 skip('(', ')');
|
|
803 token_stream.nextToken();
|
|
804 ADVANCE(';', ";");
|
|
805
|
|
806 AsmDefinitionAST *ast = CreateNode<AsmDefinitionAST>(_M_pool);
|
|
807 ast->cv = cv;
|
|
808 UPDATE_POS(ast, start, token_stream.cursor());
|
|
809 node = ast;
|
|
810
|
|
811 return true;
|
|
812 }
|
|
813
|
|
814 bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
|
|
815 {
|
|
816 std::size_t start = token_stream.cursor();
|
|
817
|
|
818 std::size_t exported = 0;
|
|
819 if (token_stream.lookAhead() == Token_export)
|
|
820 {
|
|
821 exported = token_stream.cursor();
|
|
822 token_stream.nextToken();
|
|
823 }
|
|
824
|
|
825 CHECK(Token_template);
|
|
826
|
|
827 const ListNode<TemplateParameterAST*> *params = 0;
|
|
828 if (token_stream.lookAhead() == '<')
|
|
829 {
|
|
830 token_stream.nextToken();
|
|
831 parseTemplateParameterList(params);
|
|
832
|
|
833 ADVANCE('>', ">");
|
|
834 }
|
|
835
|
|
836 DeclarationAST *declaration = 0;
|
|
837 if (!parseDeclaration(declaration))
|
|
838 {
|
|
839 reportError(("expected a declaration"));
|
|
840 }
|
|
841
|
|
842 TemplateDeclarationAST *ast = CreateNode<TemplateDeclarationAST>(_M_pool);
|
|
843 ast->exported = exported;
|
|
844 ast->template_parameters = params;
|
|
845 ast->declaration = declaration;
|
|
846
|
|
847 UPDATE_POS(ast, start, token_stream.cursor());
|
|
848 node = ast;
|
|
849
|
|
850 return true;
|
|
851 }
|
|
852
|
|
853 bool Parser::parseOperator(OperatorAST *&node)
|
|
854 {
|
|
855 std::size_t start = token_stream.cursor();
|
|
856
|
|
857 OperatorAST *ast = CreateNode<OperatorAST>(_M_pool);
|
|
858
|
|
859 switch(token_stream.lookAhead())
|
|
860 {
|
|
861 case Token_new:
|
|
862 case Token_delete:
|
|
863 {
|
|
864 ast->op = token_stream.cursor();
|
|
865 token_stream.nextToken();
|
|
866
|
|
867 if (token_stream.lookAhead() == '['
|
|
868 && token_stream.lookAhead(1) == ']')
|
|
869 {
|
|
870 ast->open = token_stream.cursor();
|
|
871 token_stream.nextToken();
|
|
872
|
|
873 ast->close = token_stream.cursor();
|
|
874 token_stream.nextToken();
|
|
875 }
|
|
876 }
|
|
877 break;
|
|
878
|
|
879 case '+':
|
|
880 case '-':
|
|
881 case '*':
|
|
882 case '/':
|
|
883 case '%':
|
|
884 case '^':
|
|
885 case '&':
|
|
886 case '|':
|
|
887 case '~':
|
|
888 case '!':
|
|
889 case '=':
|
|
890 case '<':
|
|
891 case '>':
|
|
892 case ',':
|
|
893 case Token_assign:
|
|
894 case Token_shift:
|
|
895 case Token_eq:
|
|
896 case Token_not_eq:
|
|
897 case Token_leq:
|
|
898 case Token_geq:
|
|
899 case Token_and:
|
|
900 case Token_or:
|
|
901 case Token_incr:
|
|
902 case Token_decr:
|
|
903 case Token_ptrmem:
|
|
904 case Token_arrow:
|
|
905 ast->op = token_stream.cursor();
|
|
906 token_stream.nextToken();
|
|
907 break;
|
|
908
|
|
909 default:
|
|
910 if (token_stream.lookAhead() == '('
|
|
911 && token_stream.lookAhead(1) == ')')
|
|
912 {
|
|
913 ast->op = ast->open = token_stream.cursor();
|
|
914 token_stream.nextToken();
|
|
915 ast->close = token_stream.cursor();
|
|
916 token_stream.nextToken();
|
|
917 }
|
|
918 else if (token_stream.lookAhead() == '['
|
|
919 && token_stream.lookAhead(1) == ']')
|
|
920 {
|
|
921 ast->op = ast->open = token_stream.cursor();
|
|
922 token_stream.nextToken();
|
|
923 ast->close = token_stream.cursor();
|
|
924 token_stream.nextToken();
|
|
925 }
|
|
926 else
|
|
927 {
|
|
928 return false;
|
|
929 }
|
|
930 }
|
|
931
|
|
932 UPDATE_POS(ast, start, token_stream.cursor());
|
|
933 node = ast;
|
|
934
|
|
935 return true;
|
|
936 }
|
|
937
|
|
938 bool Parser::parseCvQualify(const ListNode<std::size_t> *&node)
|
|
939 {
|
|
940 std::size_t start = token_stream.cursor();
|
|
941
|
|
942 int tk;
|
|
943 while (0 != (tk = token_stream.lookAhead())
|
|
944 && (tk == Token_const || tk == Token_volatile))
|
|
945 {
|
|
946 node = snoc(node, token_stream.cursor(), _M_pool);
|
|
947 token_stream.nextToken();
|
|
948 }
|
|
949
|
|
950 return start != token_stream.cursor();
|
|
951 }
|
|
952
|
|
953 bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
|
|
954 bool onlyIntegral)
|
|
955 {
|
|
956 std::size_t start = token_stream.cursor();
|
|
957 bool isIntegral = false;
|
|
958 bool done = false;
|
|
959
|
|
960 const ListNode<std::size_t> *integrals = 0;
|
|
961
|
|
962 while (!done)
|
|
963 {
|
|
964 switch(token_stream.lookAhead())
|
|
965 {
|
|
966 case Token_char:
|
|
967 case Token_wchar_t:
|
|
968 case Token_bool:
|
|
969 case Token_short:
|
|
970 case Token_int:
|
|
971 case Token_long:
|
|
972 case Token_signed:
|
|
973 case Token_unsigned:
|
|
974 case Token_float:
|
|
975 case Token_double:
|
|
976 case Token_void:
|
|
977 integrals = snoc(integrals, token_stream.cursor(), _M_pool);
|
|
978 isIntegral = true;
|
|
979 token_stream.nextToken();
|
|
980 break;
|
|
981
|
|
982 default:
|
|
983 done = true;
|
|
984 }
|
|
985 }
|
|
986
|
|
987 SimpleTypeSpecifierAST *ast = CreateNode<SimpleTypeSpecifierAST>(_M_pool);
|
|
988 if (isIntegral)
|
|
989 {
|
|
990 ast->integrals = integrals;
|
|
991 }
|
|
992 else if (token_stream.lookAhead() == Token___typeof)
|
|
993 {
|
|
994 ast->type_of = token_stream.cursor();
|
|
995 token_stream.nextToken();
|
|
996
|
|
997 if (token_stream.lookAhead() == '(')
|
|
998 {
|
|
999 token_stream.nextToken();
|
|
1000
|
|
1001 std::size_t saved = token_stream.cursor();
|
|
1002 parseTypeId(ast->type_id);
|
|
1003 if (token_stream.lookAhead() != ')')
|
|
1004 {
|
|
1005 ast->type_id = 0;
|
|
1006 token_stream.rewind((int) saved);
|
|
1007 parseUnaryExpression(ast->expression);
|
|
1008 }
|
|
1009 ADVANCE(')', ")");
|
|
1010 }
|
|
1011 else
|
|
1012 {
|
|
1013 parseUnaryExpression(ast->expression);
|
|
1014 }
|
|
1015 }
|
|
1016 else if (onlyIntegral)
|
|
1017 {
|
|
1018 token_stream.rewind((int) start);
|
|
1019 return false;
|
|
1020 }
|
|
1021 else
|
|
1022 {
|
|
1023 if (!parseName(ast->name, true))
|
|
1024 {
|
|
1025 ast->name = 0;
|
|
1026 token_stream.rewind((int) start);
|
|
1027 return false;
|
|
1028 }
|
|
1029 }
|
|
1030
|
|
1031 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1032 node = ast;
|
|
1033
|
|
1034 return true;
|
|
1035 }
|
|
1036
|
|
1037 bool Parser::parsePtrOperator(PtrOperatorAST *&node)
|
|
1038 {
|
|
1039 int tk = token_stream.lookAhead();
|
|
1040
|
|
1041 if (tk != '&' && tk != '*'
|
|
1042 && tk != Token_scope && tk != Token_identifier)
|
|
1043 {
|
|
1044 return false;
|
|
1045 }
|
|
1046
|
|
1047 std::size_t start = token_stream.cursor();
|
|
1048
|
|
1049 PtrOperatorAST *ast = CreateNode<PtrOperatorAST>(_M_pool);
|
|
1050
|
|
1051 switch (token_stream.lookAhead())
|
|
1052 {
|
|
1053 case '&':
|
|
1054 case '*':
|
|
1055 ast->op = token_stream.cursor();
|
|
1056 token_stream.nextToken();
|
|
1057 break;
|
|
1058
|
|
1059 case Token_scope:
|
|
1060 case Token_identifier:
|
|
1061 {
|
|
1062 if (!parsePtrToMember(ast->mem_ptr))
|
|
1063 {
|
|
1064 token_stream.rewind((int) start);
|
|
1065 return false;
|
|
1066 }
|
|
1067 }
|
|
1068 break;
|
|
1069
|
|
1070 default:
|
|
1071 Q_ASSERT(0);
|
|
1072 break;
|
|
1073 }
|
|
1074
|
|
1075 parseCvQualify(ast->cv);
|
|
1076
|
|
1077 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1078 node = ast;
|
|
1079
|
|
1080 return true;
|
|
1081 }
|
|
1082
|
|
1083 bool Parser::parseTemplateArgument(TemplateArgumentAST *&node)
|
|
1084 {
|
|
1085 std::size_t start = token_stream.cursor();
|
|
1086
|
|
1087 TypeIdAST *typeId = 0;
|
|
1088 ExpressionAST *expr = 0;
|
|
1089
|
|
1090 if (!parseTypeId(typeId) || (token_stream.lookAhead() != ','
|
|
1091 && token_stream.lookAhead() != '>'))
|
|
1092 {
|
|
1093 token_stream.rewind((int) start);
|
|
1094
|
|
1095 if (!parseLogicalOrExpression(expr, true))
|
|
1096 return false;
|
|
1097 }
|
|
1098
|
|
1099 TemplateArgumentAST *ast = CreateNode<TemplateArgumentAST>(_M_pool);
|
|
1100 ast->type_id = typeId;
|
|
1101 ast->expression = expr;
|
|
1102
|
|
1103 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1104 node = ast;
|
|
1105
|
|
1106 return true;
|
|
1107 }
|
|
1108
|
|
1109 bool Parser::parseTypeSpecifier(TypeSpecifierAST *&node)
|
|
1110 {
|
|
1111 std::size_t start = token_stream.cursor();
|
|
1112
|
|
1113 const ListNode<std::size_t> *cv = 0;
|
|
1114 parseCvQualify(cv);
|
|
1115
|
|
1116 TypeSpecifierAST *ast = 0;
|
|
1117 if (!parseElaboratedTypeSpecifier(ast) && !parseSimpleTypeSpecifier(ast))
|
|
1118 {
|
|
1119 token_stream.rewind((int) start);
|
|
1120 return false;
|
|
1121 }
|
|
1122
|
|
1123 parseCvQualify(cv);
|
|
1124 ast->cv = cv;
|
|
1125
|
|
1126 node = ast;
|
|
1127
|
|
1128 return true;
|
|
1129 }
|
|
1130
|
|
1131 bool Parser::parseDeclarator(DeclaratorAST *&node)
|
|
1132 {
|
|
1133 std::size_t start = token_stream.cursor();
|
|
1134
|
|
1135 DeclaratorAST *ast = CreateNode<DeclaratorAST>(_M_pool);
|
|
1136
|
|
1137 DeclaratorAST *decl = 0;
|
|
1138 NameAST *declId = 0;
|
|
1139
|
|
1140 PtrOperatorAST *ptrOp = 0;
|
|
1141 while (parsePtrOperator(ptrOp))
|
|
1142 {
|
|
1143 ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool);
|
|
1144 }
|
|
1145
|
|
1146 if (token_stream.lookAhead() == '(')
|
|
1147 {
|
|
1148 token_stream.nextToken();
|
|
1149
|
|
1150 if (!parseDeclarator(decl))
|
|
1151 return false;
|
|
1152
|
|
1153 ast->sub_declarator = decl;
|
|
1154
|
|
1155 CHECK(')');
|
|
1156 }
|
|
1157 else
|
|
1158 {
|
|
1159 if (token_stream.lookAhead() == ':')
|
|
1160 {
|
|
1161 // unnamed bitfield
|
|
1162 }
|
|
1163 else if (parseName(declId, true))
|
|
1164 {
|
|
1165 ast->id = declId;
|
|
1166 }
|
|
1167 else
|
|
1168 {
|
|
1169 token_stream.rewind((int) start);
|
|
1170 return false;
|
|
1171 }
|
|
1172
|
|
1173 if (token_stream.lookAhead() == ':')
|
|
1174 {
|
|
1175 token_stream.nextToken();
|
|
1176
|
|
1177 if (!parseConstantExpression(ast->bit_expression))
|
|
1178 {
|
|
1179 reportError(("Constant expression expected"));
|
|
1180 }
|
|
1181 goto update_pos;
|
|
1182 }
|
|
1183 }
|
|
1184
|
|
1185 {
|
|
1186 bool isVector = true;
|
|
1187
|
|
1188 while (token_stream.lookAhead() == '[')
|
|
1189 {
|
|
1190 token_stream.nextToken();
|
|
1191
|
|
1192 ExpressionAST *expr = 0;
|
|
1193 parseCommaExpression(expr);
|
|
1194
|
|
1195 ADVANCE(']', "]");
|
|
1196
|
|
1197 ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool);
|
|
1198 isVector = true;
|
|
1199 }
|
|
1200
|
|
1201 bool skipParen = false;
|
|
1202 if (token_stream.lookAhead() == Token_identifier
|
|
1203 && token_stream.lookAhead(1) == '('
|
|
1204 && token_stream.lookAhead(2) == '(')
|
|
1205 {
|
|
1206 token_stream.nextToken();
|
|
1207 token_stream.nextToken();
|
|
1208 skipParen = true;
|
|
1209 }
|
|
1210
|
|
1211 int tok = token_stream.lookAhead();
|
|
1212 if (ast->sub_declarator
|
|
1213 && !(isVector || tok == '(' || tok == ','
|
|
1214 || tok == ';' || tok == '='))
|
|
1215 {
|
|
1216 token_stream.rewind((int) start);
|
|
1217 return false;
|
|
1218 }
|
|
1219
|
|
1220 std::size_t index = token_stream.cursor();
|
|
1221 if (token_stream.lookAhead() == '(')
|
|
1222 {
|
|
1223 token_stream.nextToken();
|
|
1224
|
|
1225 ParameterDeclarationClauseAST *params = 0;
|
|
1226 if (!parseParameterDeclarationClause(params))
|
|
1227 {
|
|
1228 token_stream.rewind((int) index);
|
|
1229 goto update_pos;
|
|
1230 }
|
|
1231
|
|
1232 ast->parameter_declaration_clause = params;
|
|
1233
|
|
1234 if (token_stream.lookAhead() != ')')
|
|
1235 {
|
|
1236 token_stream.rewind((int) index);
|
|
1237 goto update_pos;
|
|
1238 }
|
|
1239
|
|
1240 token_stream.nextToken(); // skip ')'
|
|
1241
|
|
1242 parseCvQualify(ast->fun_cv);
|
|
1243 parseExceptionSpecification(ast->exception_spec);
|
|
1244
|
|
1245 if (token_stream.lookAhead() == Token___attribute__)
|
|
1246 {
|
|
1247 parse_Attribute__();
|
|
1248 }
|
|
1249 }
|
|
1250
|
|
1251 if (skipParen)
|
|
1252 {
|
|
1253 if (token_stream.lookAhead() != ')')
|
|
1254 {
|
|
1255 reportError(("')' expected"));
|
|
1256 }
|
|
1257 else
|
|
1258 token_stream.nextToken();
|
|
1259 }
|
|
1260 }
|
|
1261
|
|
1262 update_pos:
|
|
1263 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1264 node = ast;
|
|
1265
|
|
1266 return true;
|
|
1267 }
|
|
1268
|
|
1269 bool Parser::parseAbstractDeclarator(DeclaratorAST *&node)
|
|
1270 {
|
|
1271 std::size_t start = token_stream.cursor();
|
|
1272
|
|
1273 DeclaratorAST *ast = CreateNode<DeclaratorAST>(_M_pool);
|
|
1274 DeclaratorAST *decl = 0;
|
|
1275
|
|
1276 PtrOperatorAST *ptrOp = 0;
|
|
1277 while (parsePtrOperator(ptrOp))
|
|
1278 {
|
|
1279 ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool);
|
|
1280 }
|
|
1281
|
|
1282 int index = (int) token_stream.cursor();
|
|
1283 if (token_stream.lookAhead() == '(')
|
|
1284 {
|
|
1285 token_stream.nextToken();
|
|
1286
|
|
1287 if (!parseAbstractDeclarator(decl))
|
|
1288 {
|
|
1289 token_stream.rewind((int) index);
|
|
1290 goto label1;
|
|
1291 }
|
|
1292
|
|
1293 ast->sub_declarator = decl;
|
|
1294
|
|
1295 if (token_stream.lookAhead() != ')')
|
|
1296 {
|
|
1297 token_stream.rewind((int) start);
|
|
1298 return false;
|
|
1299 }
|
|
1300 token_stream.nextToken();
|
|
1301 }
|
|
1302 else if (token_stream.lookAhead() == ':')
|
|
1303 {
|
|
1304 token_stream.nextToken();
|
|
1305 if (!parseConstantExpression(ast->bit_expression))
|
|
1306 {
|
|
1307 ast->bit_expression = 0;
|
|
1308 reportError(("Constant expression expected"));
|
|
1309 }
|
|
1310 goto update_pos;
|
|
1311 }
|
|
1312
|
|
1313 label1:
|
|
1314 {
|
|
1315 bool isVector = true;
|
|
1316
|
|
1317 while (token_stream.lookAhead() == '[')
|
|
1318 {
|
|
1319 token_stream.nextToken();
|
|
1320
|
|
1321 ExpressionAST *expr = 0;
|
|
1322 parseCommaExpression(expr);
|
|
1323
|
|
1324 ADVANCE(']', "]");
|
|
1325
|
|
1326 ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool);
|
|
1327 isVector = true;
|
|
1328 }
|
|
1329
|
|
1330 int tok = token_stream.lookAhead();
|
|
1331 if (ast->sub_declarator
|
|
1332 && !(isVector || tok == '(' || tok == ','
|
|
1333 || tok == ';' || tok == '='))
|
|
1334 {
|
|
1335 token_stream.rewind((int) start);
|
|
1336 return false;
|
|
1337 }
|
|
1338
|
|
1339 int index = (int) token_stream.cursor();
|
|
1340 if (token_stream.lookAhead() == '(')
|
|
1341 {
|
|
1342 token_stream.nextToken();
|
|
1343
|
|
1344 ParameterDeclarationClauseAST *params = 0;
|
|
1345 if (!parseParameterDeclarationClause(params))
|
|
1346 {
|
|
1347 token_stream.rewind((int) index);
|
|
1348 goto update_pos;
|
|
1349 }
|
|
1350
|
|
1351 ast->parameter_declaration_clause = params;
|
|
1352
|
|
1353 if (token_stream.lookAhead() != ')')
|
|
1354 {
|
|
1355 token_stream.rewind((int) index);
|
|
1356 goto update_pos;
|
|
1357 }
|
|
1358
|
|
1359 token_stream.nextToken(); // skip ')'
|
|
1360
|
|
1361 parseCvQualify(ast->fun_cv);
|
|
1362 parseExceptionSpecification(ast->exception_spec);
|
|
1363 }
|
|
1364 }
|
|
1365
|
|
1366 update_pos:
|
|
1367 if (token_stream.cursor() == start)
|
|
1368 return false;
|
|
1369
|
|
1370 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1371 node = ast;
|
|
1372
|
|
1373 return true;
|
|
1374 }
|
|
1375
|
|
1376 bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node)
|
|
1377 {
|
|
1378 std::size_t start = token_stream.cursor();
|
|
1379
|
|
1380 CHECK(Token_enum);
|
|
1381
|
|
1382 NameAST *name = 0;
|
|
1383 parseName(name);
|
|
1384
|
|
1385 if (token_stream.lookAhead() != '{')
|
|
1386 {
|
|
1387 token_stream.rewind((int) start);
|
|
1388 return false;
|
|
1389 }
|
|
1390 token_stream.nextToken();
|
|
1391
|
|
1392 EnumSpecifierAST *ast = CreateNode<EnumSpecifierAST>(_M_pool);
|
|
1393 ast->name = name;
|
|
1394
|
|
1395 EnumeratorAST *enumerator = 0;
|
|
1396 if (parseEnumerator(enumerator))
|
|
1397 {
|
|
1398 ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool);
|
|
1399
|
|
1400 while (token_stream.lookAhead() == ',')
|
|
1401 {
|
|
1402 token_stream.nextToken();
|
|
1403
|
|
1404 if (!parseEnumerator(enumerator))
|
|
1405 {
|
|
1406 //reportError(("Enumerator expected"));
|
|
1407 break;
|
|
1408 }
|
|
1409
|
|
1410 ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool);
|
|
1411 }
|
|
1412 }
|
|
1413
|
|
1414 ADVANCE_NR('}', "}");
|
|
1415
|
|
1416 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1417 node = ast;
|
|
1418
|
|
1419 return true;
|
|
1420 }
|
|
1421
|
|
1422 bool Parser::parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&node)
|
|
1423 {
|
|
1424 TemplateParameterAST *param = 0;
|
|
1425 if (!parseTemplateParameter(param))
|
|
1426 return false;
|
|
1427
|
|
1428 node = snoc(node, param, _M_pool);
|
|
1429
|
|
1430 while (token_stream.lookAhead() == ',')
|
|
1431 {
|
|
1432 token_stream.nextToken();
|
|
1433
|
|
1434 if (!parseTemplateParameter(param))
|
|
1435 {
|
|
1436 syntaxError();
|
|
1437 break;
|
|
1438 }
|
|
1439 else
|
|
1440 {
|
|
1441 node = snoc(node, param, _M_pool);
|
|
1442 }
|
|
1443 }
|
|
1444
|
|
1445 return true;
|
|
1446 }
|
|
1447
|
|
1448 bool Parser::parseTemplateParameter(TemplateParameterAST *&node)
|
|
1449 {
|
|
1450 std::size_t start = token_stream.cursor();
|
|
1451 TemplateParameterAST *ast = CreateNode<TemplateParameterAST>(_M_pool);
|
|
1452
|
|
1453 int tk = token_stream.lookAhead();
|
|
1454
|
|
1455 if ((tk == Token_class || tk == Token_typename || tk == Token_template)
|
|
1456 && parseTypeParameter(ast->type_parameter))
|
|
1457 {
|
|
1458 // nothing to do
|
|
1459 }
|
|
1460 else if (!parseParameterDeclaration(ast->parameter_declaration))
|
|
1461 return false;
|
|
1462
|
|
1463 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1464 node = ast;
|
|
1465
|
|
1466 return true;
|
|
1467 }
|
|
1468
|
|
1469 bool Parser::parseTypeParameter(TypeParameterAST *&node)
|
|
1470 {
|
|
1471 std::size_t start = token_stream.cursor();
|
|
1472
|
|
1473 TypeParameterAST *ast = CreateNode<TypeParameterAST>(_M_pool);
|
|
1474 ast->type = start;
|
|
1475
|
|
1476 switch(token_stream.lookAhead())
|
|
1477 {
|
|
1478 case Token_class:
|
|
1479 case Token_typename:
|
|
1480 {
|
|
1481 token_stream.nextToken(); // skip class
|
|
1482
|
|
1483 // parse optional name
|
|
1484 if(parseName(ast->name, true))
|
|
1485 {
|
|
1486 if (token_stream.lookAhead() == '=')
|
|
1487 {
|
|
1488 token_stream.nextToken();
|
|
1489
|
|
1490 if(!parseTypeId(ast->type_id))
|
|
1491 {
|
|
1492 //syntaxError();
|
|
1493 token_stream.rewind((int) start);
|
|
1494 return false;
|
|
1495 }
|
|
1496 }
|
|
1497 else if (token_stream.lookAhead() != ','
|
|
1498 && token_stream.lookAhead() != '>')
|
|
1499 {
|
|
1500 token_stream.rewind((int) start);
|
|
1501 return false;
|
|
1502 }
|
|
1503 }
|
|
1504 }
|
|
1505 break;
|
|
1506
|
|
1507 case Token_template:
|
|
1508 {
|
|
1509 token_stream.nextToken(); // skip template
|
|
1510 ADVANCE('<', "<");
|
|
1511
|
|
1512 if (!parseTemplateParameterList(ast->template_parameters))
|
|
1513 return false;
|
|
1514
|
|
1515 ADVANCE('>', ">");
|
|
1516
|
|
1517 if (token_stream.lookAhead() == Token_class)
|
|
1518 token_stream.nextToken();
|
|
1519
|
|
1520 // parse optional name
|
|
1521 if (parseName(ast->name, true))
|
|
1522 {
|
|
1523 if (token_stream.lookAhead() == '=')
|
|
1524 {
|
|
1525 token_stream.nextToken();
|
|
1526
|
|
1527 if (!parseTypeId(ast->type_id))
|
|
1528 {
|
|
1529 syntaxError();
|
|
1530 return false;
|
|
1531 }
|
|
1532 }
|
|
1533 }
|
|
1534
|
|
1535 if (token_stream.lookAhead() == '=')
|
|
1536 {
|
|
1537 token_stream.nextToken();
|
|
1538
|
|
1539 parseName(ast->template_name, true);
|
|
1540 }
|
|
1541 }
|
|
1542 break;
|
|
1543
|
|
1544 default:
|
|
1545 return false;
|
|
1546
|
|
1547 } // end switch
|
|
1548
|
|
1549
|
|
1550 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1551 node = ast;
|
|
1552 return true;
|
|
1553 }
|
|
1554
|
|
1555 bool Parser::parseStorageClassSpecifier(const ListNode<std::size_t> *&node)
|
|
1556 {
|
|
1557 std::size_t start = token_stream.cursor();
|
|
1558
|
|
1559 int tk;
|
|
1560 while (0 != (tk = token_stream.lookAhead())
|
|
1561 && (tk == Token_friend || tk == Token_auto
|
|
1562 || tk == Token_register || tk == Token_static
|
|
1563 || tk == Token_extern || tk == Token_mutable))
|
|
1564 {
|
|
1565 node = snoc(node, token_stream.cursor(), _M_pool);
|
|
1566 token_stream.nextToken();
|
|
1567 }
|
|
1568
|
|
1569 return start != token_stream.cursor();
|
|
1570 }
|
|
1571
|
|
1572 bool Parser::parseFunctionSpecifier(const ListNode<std::size_t> *&node)
|
|
1573 {
|
|
1574 std::size_t start = token_stream.cursor();
|
|
1575
|
|
1576 int tk;
|
|
1577 while (0 != (tk = token_stream.lookAhead())
|
|
1578 && (tk == Token_inline || tk == Token_virtual
|
|
1579 || tk == Token_explicit || tk == Token_Q_INVOKABLE))
|
|
1580 {
|
|
1581 node = snoc(node, token_stream.cursor(), _M_pool);
|
|
1582 token_stream.nextToken();
|
|
1583 }
|
|
1584
|
|
1585 return start != token_stream.cursor();
|
|
1586 }
|
|
1587
|
|
1588 bool Parser::parseTypeId(TypeIdAST *&node)
|
|
1589 {
|
|
1590 /// @todo implement the AST for typeId
|
|
1591 std::size_t start = token_stream.cursor();
|
|
1592
|
|
1593 TypeSpecifierAST *spec = 0;
|
|
1594 if (!parseTypeSpecifier(spec))
|
|
1595 {
|
|
1596 token_stream.rewind((int) start);
|
|
1597 return false;
|
|
1598 }
|
|
1599
|
|
1600 DeclaratorAST *decl = 0;
|
|
1601 parseAbstractDeclarator(decl);
|
|
1602
|
|
1603 TypeIdAST *ast = CreateNode<TypeIdAST>(_M_pool);
|
|
1604 ast->type_specifier = spec;
|
|
1605 ast->declarator = decl;
|
|
1606
|
|
1607 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1608 node = ast;
|
|
1609
|
|
1610 return true;
|
|
1611 }
|
|
1612
|
|
1613 bool Parser::parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node)
|
|
1614 {
|
|
1615 InitDeclaratorAST *decl = 0;
|
|
1616 if (!parseInitDeclarator(decl))
|
|
1617 return false;
|
|
1618
|
|
1619 node = snoc(node, decl, _M_pool);
|
|
1620
|
|
1621 while (token_stream.lookAhead() == ',')
|
|
1622 {
|
|
1623 token_stream.nextToken();
|
|
1624
|
|
1625 if (!parseInitDeclarator(decl))
|
|
1626 {
|
|
1627 syntaxError();
|
|
1628 break;
|
|
1629 }
|
|
1630 node = snoc(node, decl, _M_pool);
|
|
1631 }
|
|
1632
|
|
1633 return true;
|
|
1634 }
|
|
1635
|
|
1636 bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node)
|
|
1637 {
|
|
1638 std::size_t start = token_stream.cursor();
|
|
1639
|
|
1640 ParameterDeclarationClauseAST *ast
|
|
1641 = CreateNode<ParameterDeclarationClauseAST>(_M_pool);
|
|
1642
|
|
1643 if (!parseParameterDeclarationList(ast->parameter_declarations))
|
|
1644 {
|
|
1645 if (token_stream.lookAhead() == ')')
|
|
1646 goto good;
|
|
1647
|
|
1648 if (token_stream.lookAhead() == Token_ellipsis
|
|
1649 && token_stream.lookAhead(1) == ')')
|
|
1650 {
|
|
1651 ast->ellipsis = token_stream.cursor();
|
|
1652 goto good;
|
|
1653 }
|
|
1654
|
|
1655 return false;
|
|
1656 }
|
|
1657
|
|
1658 good:
|
|
1659
|
|
1660 if (token_stream.lookAhead() == Token_ellipsis)
|
|
1661 {
|
|
1662 ast->ellipsis = token_stream.cursor();
|
|
1663 token_stream.nextToken();
|
|
1664 }
|
|
1665
|
|
1666 /// @todo add ellipsis
|
|
1667 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1668 node = ast;
|
|
1669
|
|
1670 return true;
|
|
1671 }
|
|
1672
|
|
1673 bool Parser::parseParameterDeclarationList(const ListNode<ParameterDeclarationAST*> *&node)
|
|
1674 {
|
|
1675 std::size_t start = token_stream.cursor();
|
|
1676
|
|
1677 ParameterDeclarationAST *param = 0;
|
|
1678 if (!parseParameterDeclaration(param))
|
|
1679 {
|
|
1680 token_stream.rewind((int) start);
|
|
1681 return false;
|
|
1682 }
|
|
1683
|
|
1684 node = snoc(node, param, _M_pool);
|
|
1685
|
|
1686 while (token_stream.lookAhead() == ',')
|
|
1687 {
|
|
1688 token_stream.nextToken();
|
|
1689
|
|
1690 if (token_stream.lookAhead() == Token_ellipsis)
|
|
1691 break;
|
|
1692
|
|
1693 if (!parseParameterDeclaration(param))
|
|
1694 {
|
|
1695 token_stream.rewind((int) start);
|
|
1696 return false;
|
|
1697 }
|
|
1698 node = snoc(node, param, _M_pool);
|
|
1699 }
|
|
1700
|
|
1701 return true;
|
|
1702 }
|
|
1703
|
|
1704 bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
|
|
1705 {
|
|
1706 std::size_t start = token_stream.cursor();
|
|
1707
|
|
1708 const ListNode<std::size_t> *storage = 0;
|
|
1709 parseStorageClassSpecifier(storage);
|
|
1710
|
|
1711 // parse decl spec
|
|
1712 TypeSpecifierAST *spec = 0;
|
|
1713 if (!parseTypeSpecifier(spec))
|
|
1714 {
|
|
1715 token_stream.rewind((int) start);
|
|
1716 return false;
|
|
1717 }
|
|
1718
|
|
1719 int index = (int) token_stream.cursor();
|
|
1720
|
|
1721 DeclaratorAST *decl = 0;
|
|
1722 if (!parseDeclarator(decl))
|
|
1723 {
|
|
1724 token_stream.rewind((int) index);
|
|
1725
|
|
1726 // try with abstract declarator
|
|
1727 parseAbstractDeclarator(decl);
|
|
1728 }
|
|
1729
|
|
1730 ExpressionAST *expr = 0;
|
|
1731 if (token_stream.lookAhead() == '=')
|
|
1732 {
|
|
1733 token_stream.nextToken();
|
|
1734 if (!parseLogicalOrExpression(expr,true))
|
|
1735 {
|
|
1736 //reportError(("Expression expected"));
|
|
1737 }
|
|
1738 }
|
|
1739
|
|
1740 ParameterDeclarationAST *ast = CreateNode<ParameterDeclarationAST>(_M_pool);
|
|
1741 ast->type_specifier = spec;
|
|
1742 ast->declarator = decl;
|
|
1743 ast->expression = expr;
|
|
1744
|
|
1745 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1746 node = ast;
|
|
1747
|
|
1748 return true;
|
|
1749 }
|
|
1750
|
|
1751 bool Parser::parse_Attribute__() {
|
|
1752 token_stream.nextToken();
|
|
1753
|
|
1754 ADVANCE('(', "(");
|
|
1755
|
|
1756 ExpressionAST *expr = 0;
|
|
1757 parseExpression(expr);
|
|
1758
|
|
1759 if (token_stream.lookAhead() != ')')
|
|
1760 {
|
|
1761 reportError(("')' expected"));
|
|
1762 return false;
|
|
1763 }
|
|
1764 else
|
|
1765 {
|
|
1766 token_stream.nextToken();
|
|
1767 }
|
|
1768 return true;
|
|
1769 }
|
|
1770
|
|
1771 QString Parser::tokenText(AST *ast) const
|
|
1772 {
|
|
1773 if (ast == 0) return QString();
|
|
1774
|
|
1775 int start_token = ast->start_token;
|
|
1776 int end_token = ast->end_token;
|
|
1777
|
|
1778 Token const &tk = token_stream.token (start_token);
|
|
1779 Token const &end_tk = token_stream.token(end_token);
|
|
1780
|
|
1781 return QString::fromLatin1 (&tk.text[tk.position],(int) (end_tk.position - tk.position)).trimmed();
|
|
1782 }
|
|
1783
|
|
1784 bool Parser::parseForwardDeclarationSpecifier(TypeSpecifierAST *&node)
|
|
1785 {
|
|
1786 std::size_t start = token_stream.cursor();
|
|
1787
|
|
1788 int kind = token_stream.lookAhead();
|
|
1789 if (kind != Token_class && kind != Token_struct && kind != Token_union)
|
|
1790 return false;
|
|
1791
|
|
1792 std::size_t class_key = token_stream.cursor();
|
|
1793 token_stream.nextToken();
|
|
1794
|
|
1795 NameAST *name = 0;
|
|
1796 if (!parseName(name, false)) {
|
|
1797 token_stream.rewind((int) start);
|
|
1798 return false;
|
|
1799 }
|
|
1800
|
|
1801 BaseClauseAST *bases = 0;
|
|
1802 if (token_stream.lookAhead() == ':')
|
|
1803 {
|
|
1804 if (!parseBaseClause(bases))
|
|
1805 {
|
|
1806 token_stream.rewind((int) start);
|
|
1807 return false;
|
|
1808 }
|
|
1809 }
|
|
1810
|
|
1811 if (token_stream.lookAhead() != ';')
|
|
1812 {
|
|
1813 token_stream.rewind((int) start);
|
|
1814 return false;
|
|
1815 }
|
|
1816
|
|
1817 ForwardDeclarationSpecifierAST *ast = CreateNode<ForwardDeclarationSpecifierAST>(_M_pool);
|
|
1818 ast->class_key = class_key;
|
|
1819 ast->name = name;
|
|
1820 ast->base_clause = bases;
|
|
1821
|
|
1822 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1823 node = ast;
|
|
1824
|
|
1825 return true;
|
|
1826 }
|
|
1827
|
|
1828 bool Parser::parseClassSpecifier(TypeSpecifierAST *&node)
|
|
1829 {
|
|
1830 std::size_t start = token_stream.cursor();
|
|
1831
|
|
1832 int kind = token_stream.lookAhead();
|
|
1833 if (kind != Token_class && kind != Token_struct && kind != Token_union)
|
|
1834 return false;
|
|
1835
|
|
1836 std::size_t class_key = token_stream.cursor();
|
|
1837 token_stream.nextToken();
|
|
1838
|
|
1839 WinDeclSpecAST *winDeclSpec = 0;
|
|
1840 parseWinDeclSpec(winDeclSpec);
|
|
1841
|
|
1842 if (token_stream.lookAhead() == Token___attribute__) {
|
|
1843 parse_Attribute__();
|
|
1844 }
|
|
1845
|
|
1846 while (token_stream.lookAhead() == Token_identifier
|
|
1847 && token_stream.lookAhead(1) == Token_identifier)
|
|
1848 {
|
|
1849 token_stream.nextToken();
|
|
1850 }
|
|
1851
|
|
1852 NameAST *name = 0;
|
|
1853 parseName(name, true);
|
|
1854
|
|
1855 BaseClauseAST *bases = 0;
|
|
1856
|
|
1857 if (token_stream.lookAhead() == ':')
|
|
1858 {
|
|
1859 if (!parseBaseClause(bases))
|
|
1860 {
|
|
1861 skipUntil('{');
|
|
1862 }
|
|
1863 }
|
|
1864
|
|
1865 if (token_stream.lookAhead() != '{')
|
|
1866 {
|
|
1867
|
|
1868 token_stream.rewind((int) start);
|
|
1869 return false;
|
|
1870 }
|
|
1871
|
|
1872 ADVANCE('{', "{");
|
|
1873
|
|
1874 ClassSpecifierAST *ast = CreateNode<ClassSpecifierAST>(_M_pool);
|
|
1875 ast->win_decl_specifiers = winDeclSpec;
|
|
1876 ast->class_key = class_key;
|
|
1877 ast->name = name;
|
|
1878 ast->base_clause = bases;
|
|
1879
|
|
1880 while (token_stream.lookAhead())
|
|
1881 {
|
|
1882 if (token_stream.lookAhead() == '}')
|
|
1883 break;
|
|
1884
|
|
1885 std::size_t startDecl = token_stream.cursor();
|
|
1886
|
|
1887 DeclarationAST *memSpec = 0;
|
|
1888 if (!parseMemberSpecification(memSpec))
|
|
1889 {
|
|
1890 if (startDecl == token_stream.cursor())
|
|
1891 token_stream.nextToken(); // skip at least one token
|
|
1892 skipUntilDeclaration();
|
|
1893 }
|
|
1894 else
|
|
1895 ast->member_specs = snoc(ast->member_specs, memSpec, _M_pool);
|
|
1896 }
|
|
1897
|
|
1898 ADVANCE_NR('}', "}");
|
|
1899
|
|
1900 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1901 node = ast;
|
|
1902
|
|
1903 return true;
|
|
1904 }
|
|
1905
|
|
1906 bool Parser::parseAccessSpecifier(DeclarationAST *&node)
|
|
1907 {
|
|
1908 std::size_t start = token_stream.cursor();
|
|
1909
|
|
1910 const ListNode<std::size_t> *specs = 0;
|
|
1911
|
|
1912 bool done = false;
|
|
1913 while (!done)
|
|
1914 {
|
|
1915 switch(token_stream.lookAhead())
|
|
1916 {
|
|
1917 case Token_signals:
|
|
1918 case Token_slots:
|
|
1919 case Token_k_dcop:
|
|
1920 case Token_k_dcop_signals:
|
|
1921 case Token_public:
|
|
1922 case Token_protected:
|
|
1923 case Token_private:
|
|
1924 specs = snoc(specs, token_stream.cursor(), _M_pool);
|
|
1925 token_stream.nextToken();
|
|
1926 break;
|
|
1927
|
|
1928 default:
|
|
1929 done = true;
|
|
1930 break;
|
|
1931 }
|
|
1932 }
|
|
1933
|
|
1934 if (!specs)
|
|
1935 return false;
|
|
1936
|
|
1937 ADVANCE(':', ":");
|
|
1938
|
|
1939 AccessSpecifierAST *ast = CreateNode<AccessSpecifierAST>(_M_pool);
|
|
1940 ast->specs = specs;
|
|
1941 UPDATE_POS(ast, start, token_stream.cursor());
|
|
1942 node = ast;
|
|
1943
|
|
1944 return true;
|
|
1945 }
|
|
1946
|
|
1947 bool Parser::parseMemberSpecification(DeclarationAST *&node)
|
|
1948 {
|
|
1949 std::size_t start = token_stream.cursor();
|
|
1950
|
|
1951 if (token_stream.lookAhead() == ';')
|
|
1952 {
|
|
1953 token_stream.nextToken();
|
|
1954 return true;
|
|
1955 }
|
|
1956 else if (token_stream.lookAhead() == Token_Q_OBJECT || token_stream.lookAhead() == Token_K_DCOP)
|
|
1957 {
|
|
1958 token_stream.nextToken();
|
|
1959 return true;
|
|
1960 }
|
|
1961 else if (parseTypedef(node))
|
|
1962 {
|
|
1963 return true;
|
|
1964 }
|
|
1965 else if (parseUsing(node))
|
|
1966 {
|
|
1967 return true;
|
|
1968 }
|
|
1969 else if (parseTemplateDeclaration(node))
|
|
1970 {
|
|
1971 return true;
|
|
1972 }
|
|
1973 else if (parseAccessSpecifier(node))
|
|
1974 {
|
|
1975 return true;
|
|
1976 }
|
|
1977 else if (parseQ_PROPERTY(node))
|
|
1978 {
|
|
1979 return true;
|
|
1980 }
|
|
1981 else if (parseQ_ENUMS(node))
|
|
1982 {
|
|
1983 return true;
|
|
1984 }
|
|
1985
|
|
1986 token_stream.rewind((int) start);
|
|
1987
|
|
1988 const ListNode<std::size_t> *cv = 0;
|
|
1989 parseCvQualify(cv);
|
|
1990
|
|
1991 const ListNode<std::size_t> *storageSpec = 0;
|
|
1992 parseStorageClassSpecifier(storageSpec);
|
|
1993
|
|
1994 parseCvQualify(cv);
|
|
1995
|
|
1996 TypeSpecifierAST *spec = 0;
|
|
1997 if (parseEnumSpecifier(spec) || parseClassSpecifier(spec))
|
|
1998 {
|
|
1999 parseCvQualify(cv);
|
|
2000 spec->cv = cv;
|
|
2001
|
|
2002 const ListNode<InitDeclaratorAST*> *declarators = 0;
|
|
2003 parseInitDeclaratorList(declarators);
|
|
2004 ADVANCE(';', ";");
|
|
2005
|
|
2006 SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool);
|
|
2007 ast->type_specifier = spec;
|
|
2008 ast->init_declarators = declarators;
|
|
2009 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2010 node = ast;
|
|
2011
|
|
2012 return true;
|
|
2013 }
|
|
2014
|
|
2015 token_stream.rewind((int) start);
|
|
2016 return parseDeclarationInternal(node);
|
|
2017 }
|
|
2018
|
|
2019 bool Parser::parseCtorInitializer(CtorInitializerAST *&node)
|
|
2020 {
|
|
2021 std::size_t start = token_stream.cursor();
|
|
2022
|
|
2023 CHECK(':');
|
|
2024
|
|
2025 CtorInitializerAST *ast = CreateNode<CtorInitializerAST>(_M_pool);
|
|
2026 ast->colon = start;
|
|
2027
|
|
2028 if (!parseMemInitializerList(ast->member_initializers))
|
|
2029 {
|
|
2030 reportError(("Member initializers expected"));
|
|
2031 }
|
|
2032
|
|
2033 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2034 node = ast;
|
|
2035
|
|
2036 return true;
|
|
2037 }
|
|
2038
|
|
2039 bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST *&node)
|
|
2040 {
|
|
2041 std::size_t start = token_stream.cursor();
|
|
2042
|
|
2043 int tk = token_stream.lookAhead();
|
|
2044 if (tk == Token_class ||
|
|
2045 tk == Token_struct ||
|
|
2046 tk == Token_union ||
|
|
2047 tk == Token_enum ||
|
|
2048 tk == Token_typename)
|
|
2049 {
|
|
2050 std::size_t type = token_stream.cursor();
|
|
2051 token_stream.nextToken();
|
|
2052
|
|
2053 NameAST *name = 0;
|
|
2054 if (parseName(name, true))
|
|
2055 {
|
|
2056 ElaboratedTypeSpecifierAST *ast
|
|
2057 = CreateNode<ElaboratedTypeSpecifierAST>(_M_pool);
|
|
2058
|
|
2059 ast->type = type;
|
|
2060 ast->name = name;
|
|
2061
|
|
2062 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2063 node = ast;
|
|
2064
|
|
2065 return true;
|
|
2066 }
|
|
2067 }
|
|
2068
|
|
2069 token_stream.rewind((int) start);
|
|
2070 return false;
|
|
2071 }
|
|
2072
|
|
2073 bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node)
|
|
2074 {
|
|
2075 std::size_t start = token_stream.cursor();
|
|
2076
|
|
2077 CHECK(Token_throw);
|
|
2078 ADVANCE('(', "(");
|
|
2079
|
|
2080 ExceptionSpecificationAST *ast
|
|
2081 = CreateNode<ExceptionSpecificationAST>(_M_pool);
|
|
2082
|
|
2083 if (token_stream.lookAhead() == Token_ellipsis)
|
|
2084 {
|
|
2085 ast->ellipsis = token_stream.cursor();
|
|
2086 token_stream.nextToken();
|
|
2087 }
|
|
2088 else
|
|
2089 {
|
|
2090 parseTypeIdList(ast->type_ids);
|
|
2091 }
|
|
2092
|
|
2093 ADVANCE(')', ")");
|
|
2094
|
|
2095 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2096 node = ast;
|
|
2097
|
|
2098 return true;
|
|
2099 }
|
|
2100
|
|
2101 bool Parser::parseEnumerator(EnumeratorAST *&node)
|
|
2102 {
|
|
2103 std::size_t start = token_stream.cursor();
|
|
2104
|
|
2105 CHECK(Token_identifier);
|
|
2106 std::size_t id = token_stream.cursor() - 1;
|
|
2107
|
|
2108 EnumeratorAST *ast = CreateNode<EnumeratorAST>(_M_pool);
|
|
2109 ast->id = id;
|
|
2110
|
|
2111 if (token_stream.lookAhead() == '=')
|
|
2112 {
|
|
2113 token_stream.nextToken();
|
|
2114
|
|
2115 if (!parseConstantExpression(ast->expression))
|
|
2116 {
|
|
2117 reportError(("Constant expression expected"));
|
|
2118 }
|
|
2119 }
|
|
2120
|
|
2121 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2122 node = ast;
|
|
2123
|
|
2124 return true;
|
|
2125 }
|
|
2126
|
|
2127 bool Parser::parseInitDeclarator(InitDeclaratorAST *&node)
|
|
2128 {
|
|
2129 std::size_t start = token_stream.cursor();
|
|
2130
|
|
2131 DeclaratorAST *decl = 0;
|
|
2132 if (!parseDeclarator(decl))
|
|
2133 {
|
|
2134 return false;
|
|
2135 }
|
|
2136
|
|
2137 if (token_stream.lookAhead(0) == Token_asm)
|
|
2138 {
|
|
2139 token_stream.nextToken();
|
|
2140 skip('(', ')');
|
|
2141 token_stream.nextToken();
|
|
2142 }
|
|
2143
|
|
2144 InitializerAST *init = 0;
|
|
2145 parseInitializer(init);
|
|
2146
|
|
2147 InitDeclaratorAST *ast = CreateNode<InitDeclaratorAST>(_M_pool);
|
|
2148 ast->declarator = decl;
|
|
2149 ast->initializer = init;
|
|
2150
|
|
2151 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2152 node = ast;
|
|
2153
|
|
2154 return true;
|
|
2155 }
|
|
2156
|
|
2157 bool Parser::parseBaseClause(BaseClauseAST *&node)
|
|
2158 {
|
|
2159 std::size_t start = token_stream.cursor();
|
|
2160
|
|
2161 CHECK(':');
|
|
2162
|
|
2163 BaseSpecifierAST *baseSpec = 0;
|
|
2164 if (!parseBaseSpecifier(baseSpec))
|
|
2165 return false;
|
|
2166
|
|
2167 BaseClauseAST *ast = CreateNode<BaseClauseAST>(_M_pool);
|
|
2168 ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool);
|
|
2169
|
|
2170 while (token_stream.lookAhead() == ',')
|
|
2171 {
|
|
2172 token_stream.nextToken();
|
|
2173
|
|
2174 if (!parseBaseSpecifier(baseSpec))
|
|
2175 {
|
|
2176 reportError(("Base class specifier expected"));
|
|
2177 break;
|
|
2178 }
|
|
2179 ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool);
|
|
2180 }
|
|
2181
|
|
2182 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2183 node = ast;
|
|
2184
|
|
2185 return true;
|
|
2186 }
|
|
2187
|
|
2188 bool Parser::parseInitializer(InitializerAST *&node)
|
|
2189 {
|
|
2190 std::size_t start = token_stream.cursor();
|
|
2191
|
|
2192 int tk = token_stream.lookAhead();
|
|
2193 if (tk != '=' && tk != '(')
|
|
2194 return false;
|
|
2195
|
|
2196 InitializerAST *ast = CreateNode<InitializerAST>(_M_pool);
|
|
2197
|
|
2198 if (tk == '=')
|
|
2199 {
|
|
2200 token_stream.nextToken();
|
|
2201
|
|
2202 if (!parseInitializerClause(ast->initializer_clause))
|
|
2203 {
|
|
2204 reportError(("Initializer clause expected"));
|
|
2205 }
|
|
2206 }
|
|
2207 else if (tk == '(')
|
|
2208 {
|
|
2209 token_stream.nextToken();
|
|
2210 parseCommaExpression(ast->expression);
|
|
2211 CHECK(')');
|
|
2212 }
|
|
2213
|
|
2214 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2215 node = ast;
|
|
2216
|
|
2217 return true;
|
|
2218 }
|
|
2219
|
|
2220 bool Parser::parseMemInitializerList(const ListNode<MemInitializerAST*> *&node)
|
|
2221 {
|
|
2222 MemInitializerAST *init = 0;
|
|
2223
|
|
2224 if (!parseMemInitializer(init))
|
|
2225 return false;
|
|
2226
|
|
2227 node = snoc(node, init, _M_pool);
|
|
2228
|
|
2229 while (token_stream.lookAhead() == ',')
|
|
2230 {
|
|
2231 token_stream.nextToken();
|
|
2232
|
|
2233 if (!parseMemInitializer(init))
|
|
2234 break;
|
|
2235
|
|
2236 node = snoc(node, init, _M_pool);
|
|
2237 }
|
|
2238
|
|
2239 return true;
|
|
2240 }
|
|
2241
|
|
2242 bool Parser::parseMemInitializer(MemInitializerAST *&node)
|
|
2243 {
|
|
2244 std::size_t start = token_stream.cursor();
|
|
2245
|
|
2246 NameAST *initId = 0;
|
|
2247 if (!parseName(initId, true))
|
|
2248 {
|
|
2249 reportError(("Identifier expected"));
|
|
2250 return false;
|
|
2251 }
|
|
2252
|
|
2253 ADVANCE('(', "(");
|
|
2254 ExpressionAST *expr = 0;
|
|
2255 parseCommaExpression(expr);
|
|
2256 ADVANCE(')', ")");
|
|
2257
|
|
2258 MemInitializerAST *ast = CreateNode<MemInitializerAST>(_M_pool);
|
|
2259 ast->initializer_id = initId;
|
|
2260 ast->expression = expr;
|
|
2261
|
|
2262 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2263 node = ast;
|
|
2264
|
|
2265 return true;
|
|
2266 }
|
|
2267
|
|
2268 bool Parser::parseTypeIdList(const ListNode<TypeIdAST*> *&node)
|
|
2269 {
|
|
2270 TypeIdAST *typeId = 0;
|
|
2271 if (!parseTypeId(typeId))
|
|
2272 return false;
|
|
2273
|
|
2274 node = snoc(node, typeId, _M_pool);
|
|
2275
|
|
2276 while (token_stream.lookAhead() == ',')
|
|
2277 {
|
|
2278 token_stream.nextToken();
|
|
2279 if (parseTypeId(typeId))
|
|
2280 {
|
|
2281 node = snoc(node, typeId, _M_pool);
|
|
2282 }
|
|
2283 else
|
|
2284 {
|
|
2285 reportError(("Type id expected"));
|
|
2286 break;
|
|
2287 }
|
|
2288 }
|
|
2289
|
|
2290 return true;
|
|
2291 }
|
|
2292
|
|
2293 bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node)
|
|
2294 {
|
|
2295 std::size_t start = token_stream.cursor();
|
|
2296
|
|
2297 BaseSpecifierAST *ast = CreateNode<BaseSpecifierAST>(_M_pool);
|
|
2298
|
|
2299 if (token_stream.lookAhead() == Token_virtual)
|
|
2300 {
|
|
2301 ast->virt = token_stream.cursor();
|
|
2302 token_stream.nextToken();
|
|
2303
|
|
2304 int tk = token_stream.lookAhead();
|
|
2305 if (tk == Token_public || tk == Token_protected
|
|
2306 || tk == Token_private)
|
|
2307 {
|
|
2308 ast->access_specifier = token_stream.cursor();
|
|
2309 token_stream.nextToken();
|
|
2310 }
|
|
2311 }
|
|
2312 else
|
|
2313 {
|
|
2314 int tk = token_stream.lookAhead();
|
|
2315 if (tk == Token_public || tk == Token_protected
|
|
2316 || tk == Token_private)
|
|
2317 {
|
|
2318 ast->access_specifier = token_stream.cursor();
|
|
2319 token_stream.nextToken();
|
|
2320 }
|
|
2321
|
|
2322 if (token_stream.lookAhead() == Token_virtual)
|
|
2323 {
|
|
2324 ast->virt = token_stream.cursor();
|
|
2325 token_stream.nextToken();
|
|
2326 }
|
|
2327 }
|
|
2328
|
|
2329 if (!parseName(ast->name, true))
|
|
2330 reportError(("Class name expected"));
|
|
2331
|
|
2332 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2333 node = ast;
|
|
2334
|
|
2335 return true;
|
|
2336 }
|
|
2337
|
|
2338 bool Parser::parseInitializerClause(InitializerClauseAST *&node)
|
|
2339 {
|
|
2340 std::size_t start = token_stream.cursor();
|
|
2341
|
|
2342 InitializerClauseAST *ast = CreateNode<InitializerClauseAST>(_M_pool);
|
|
2343
|
|
2344 if (token_stream.lookAhead() == '{')
|
|
2345 {
|
|
2346 #if defined(__GNUC__)
|
|
2347 #warning "implement me"
|
|
2348 #endif
|
|
2349 if (skip('{','}'))
|
|
2350 token_stream.nextToken();
|
|
2351 else
|
|
2352 reportError(("} missing"));
|
|
2353 }
|
|
2354 else
|
|
2355 {
|
|
2356 if (!parseAssignmentExpression(ast->expression))
|
|
2357 {
|
|
2358 //reportError(("Expression expected"));
|
|
2359 }
|
|
2360 }
|
|
2361
|
|
2362 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2363 node = ast;
|
|
2364
|
|
2365 return true;
|
|
2366 }
|
|
2367
|
|
2368 bool Parser::parsePtrToMember(PtrToMemberAST *&node)
|
|
2369 {
|
|
2370 #if defined(__GNUC__)
|
|
2371 #warning "implemente me (AST)"
|
|
2372 #endif
|
|
2373
|
|
2374 std::size_t start = token_stream.cursor();
|
|
2375
|
|
2376 std::size_t global_scope = 0;
|
|
2377 if (token_stream.lookAhead() == Token_scope)
|
|
2378 {
|
|
2379 global_scope = token_stream.cursor();
|
|
2380 token_stream.nextToken();
|
|
2381 }
|
|
2382
|
|
2383 UnqualifiedNameAST *name = 0;
|
|
2384 while (token_stream.lookAhead() == Token_identifier)
|
|
2385 {
|
|
2386 if (!parseUnqualifiedName(name))
|
|
2387 break;
|
|
2388
|
|
2389 if (token_stream.lookAhead() == Token_scope
|
|
2390 && token_stream.lookAhead(1) == '*')
|
|
2391 {
|
|
2392 token_stream.nextToken();
|
|
2393 token_stream.nextToken();
|
|
2394
|
|
2395 PtrToMemberAST *ast = CreateNode<PtrToMemberAST>(_M_pool);
|
|
2396 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2397 node = ast;
|
|
2398
|
|
2399 return true;
|
|
2400 }
|
|
2401
|
|
2402 if (token_stream.lookAhead() == Token_scope)
|
|
2403 token_stream.nextToken();
|
|
2404 }
|
|
2405
|
|
2406 token_stream.rewind((int) start);
|
|
2407 return false;
|
|
2408 }
|
|
2409
|
|
2410 bool Parser::parseUnqualifiedName(UnqualifiedNameAST *&node,
|
|
2411 bool parseTemplateId)
|
|
2412 {
|
|
2413 std::size_t start = token_stream.cursor();
|
|
2414
|
|
2415 std::size_t tilde = 0;
|
|
2416 std::size_t id = 0;
|
|
2417 OperatorFunctionIdAST *operator_id = 0;
|
|
2418
|
|
2419 if (token_stream.lookAhead() == Token_identifier)
|
|
2420 {
|
|
2421 id = token_stream.cursor();
|
|
2422 token_stream.nextToken();
|
|
2423 }
|
|
2424 else if (token_stream.lookAhead() == '~'
|
|
2425 && token_stream.lookAhead(1) == Token_identifier)
|
|
2426 {
|
|
2427 tilde = token_stream.cursor();
|
|
2428 token_stream.nextToken(); // skip ~
|
|
2429
|
|
2430 id = token_stream.cursor();
|
|
2431 token_stream.nextToken(); // skip classname
|
|
2432 }
|
|
2433 else if (token_stream.lookAhead() == Token_operator)
|
|
2434 {
|
|
2435 if (!parseOperatorFunctionId(operator_id))
|
|
2436 return false;
|
|
2437 }
|
|
2438 else
|
|
2439 {
|
|
2440 return false;
|
|
2441 }
|
|
2442
|
|
2443 UnqualifiedNameAST *ast = CreateNode<UnqualifiedNameAST>(_M_pool);
|
|
2444 ast->tilde = tilde;
|
|
2445 ast->id = id;
|
|
2446 ast->operator_id = operator_id;
|
|
2447
|
|
2448 if (parseTemplateId && !tilde)
|
|
2449 {
|
|
2450 std::size_t index = token_stream.cursor();
|
|
2451
|
|
2452 if (token_stream.lookAhead() == '<')
|
|
2453 {
|
|
2454 token_stream.nextToken();
|
|
2455
|
|
2456 // optional template arguments
|
|
2457 parseTemplateArgumentList(ast->template_arguments);
|
|
2458
|
|
2459 if (token_stream.lookAhead() == '>')
|
|
2460 {
|
|
2461 token_stream.nextToken();
|
|
2462 }
|
|
2463 else
|
|
2464 {
|
|
2465 ast->template_arguments = 0;
|
|
2466 token_stream.rewind((int) index);
|
|
2467 }
|
|
2468 }
|
|
2469 }
|
|
2470
|
|
2471 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2472 node = ast;
|
|
2473
|
|
2474 return true;
|
|
2475 }
|
|
2476
|
|
2477 bool Parser::parseStringLiteral(StringLiteralAST *&node)
|
|
2478 {
|
|
2479 std::size_t start = token_stream.cursor();
|
|
2480
|
|
2481 if (token_stream.lookAhead() != Token_string_literal)
|
|
2482 return false;
|
|
2483
|
|
2484 StringLiteralAST *ast = CreateNode<StringLiteralAST>(_M_pool);
|
|
2485
|
|
2486 while (token_stream.lookAhead() == Token_string_literal)
|
|
2487 {
|
|
2488 ast->literals = snoc(ast->literals, token_stream.cursor(), _M_pool);
|
|
2489 token_stream.nextToken();
|
|
2490 }
|
|
2491
|
|
2492 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2493 node = ast;
|
|
2494
|
|
2495 return true;
|
|
2496 }
|
|
2497
|
|
2498 bool Parser::parseExpressionStatement(StatementAST *&node)
|
|
2499 {
|
|
2500 std::size_t start = token_stream.cursor();
|
|
2501
|
|
2502 ExpressionAST *expr = 0;
|
|
2503 parseCommaExpression(expr);
|
|
2504
|
|
2505 ADVANCE(';', ";");
|
|
2506
|
|
2507 ExpressionStatementAST *ast = CreateNode<ExpressionStatementAST>(_M_pool);
|
|
2508 ast->expression = expr;
|
|
2509
|
|
2510 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2511 node = ast;
|
|
2512
|
|
2513 return true;
|
|
2514 }
|
|
2515
|
|
2516 bool Parser::parseStatement(StatementAST *&node)
|
|
2517 {
|
|
2518 std::size_t start = token_stream.cursor();
|
|
2519
|
|
2520 switch(token_stream.lookAhead())
|
|
2521 {
|
|
2522 case Token_while:
|
|
2523 return parseWhileStatement(node);
|
|
2524
|
|
2525 case Token_do:
|
|
2526 return parseDoStatement(node);
|
|
2527
|
|
2528 case Token_for:
|
|
2529 return parseForStatement(node);
|
|
2530
|
|
2531 case Token_if:
|
|
2532 return parseIfStatement(node);
|
|
2533
|
|
2534 case Token_switch:
|
|
2535 return parseSwitchStatement(node);
|
|
2536
|
|
2537 case Token_try:
|
|
2538 return parseTryBlockStatement(node);
|
|
2539
|
|
2540 case Token_case:
|
|
2541 case Token_default:
|
|
2542 return parseLabeledStatement(node);
|
|
2543
|
|
2544 case Token_break:
|
|
2545 case Token_continue:
|
|
2546 #if defined(__GNUC__)
|
|
2547 #warning "implement me"
|
|
2548 #endif
|
|
2549 token_stream.nextToken();
|
|
2550 ADVANCE(';', ";");
|
|
2551 return true;
|
|
2552
|
|
2553 case Token_goto:
|
|
2554 #if defined(__GNUC__)
|
|
2555 #warning "implement me"
|
|
2556 #endif
|
|
2557 token_stream.nextToken();
|
|
2558 ADVANCE(Token_identifier, "identifier");
|
|
2559 ADVANCE(';', ";");
|
|
2560 return true;
|
|
2561
|
|
2562 case Token_return:
|
|
2563 {
|
|
2564 token_stream.nextToken();
|
|
2565 ExpressionAST *expr = 0;
|
|
2566 parseCommaExpression(expr);
|
|
2567
|
|
2568 ADVANCE(';', ";");
|
|
2569
|
|
2570 ReturnStatementAST *ast = CreateNode<ReturnStatementAST>(_M_pool);
|
|
2571 ast->expression = expr;
|
|
2572
|
|
2573 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2574 node = ast;
|
|
2575 }
|
|
2576 return true;
|
|
2577
|
|
2578 case '{':
|
|
2579 return parseCompoundStatement(node);
|
|
2580
|
|
2581 case Token_identifier:
|
|
2582 if (parseLabeledStatement(node))
|
|
2583 return true;
|
|
2584 break;
|
|
2585 }
|
|
2586
|
|
2587 return parseExpressionOrDeclarationStatement(node);
|
|
2588 }
|
|
2589
|
|
2590 bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
|
|
2591 {
|
|
2592 bool blocked = block_errors(true);
|
|
2593
|
|
2594 std::size_t start = token_stream.cursor();
|
|
2595
|
|
2596 StatementAST *decl_ast = 0;
|
|
2597 bool maybe_amb = parseDeclarationStatement(decl_ast);
|
|
2598 maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';';
|
|
2599
|
|
2600 std::size_t end = token_stream.cursor();
|
|
2601
|
|
2602 token_stream.rewind((int) start);
|
|
2603 StatementAST *expr_ast = 0;
|
|
2604 maybe_amb &= parseExpressionStatement(expr_ast);
|
|
2605 maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';';
|
|
2606
|
|
2607 if (maybe_amb)
|
|
2608 {
|
|
2609 Q_ASSERT(decl_ast != 0 && expr_ast != 0);
|
|
2610 ExpressionOrDeclarationStatementAST *ast
|
|
2611 = CreateNode<ExpressionOrDeclarationStatementAST>(_M_pool);
|
|
2612 ast->declaration = decl_ast;
|
|
2613 ast->expression = expr_ast;
|
|
2614
|
|
2615 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2616 node = ast;
|
|
2617 }
|
|
2618 else
|
|
2619 {
|
|
2620 token_stream.rewind((int) std::max(end, token_stream.cursor()));
|
|
2621
|
|
2622 node = decl_ast;
|
|
2623 if (!node)
|
|
2624 node = expr_ast;
|
|
2625 }
|
|
2626
|
|
2627 block_errors(blocked);
|
|
2628
|
|
2629 if (!node)
|
|
2630 syntaxError();
|
|
2631
|
|
2632 return node != 0;
|
|
2633 }
|
|
2634
|
|
2635 bool Parser::parseCondition(ConditionAST *&node, bool initRequired)
|
|
2636 {
|
|
2637 std::size_t start = token_stream.cursor();
|
|
2638
|
|
2639 ConditionAST *ast = CreateNode<ConditionAST>(_M_pool);
|
|
2640 TypeSpecifierAST *spec = 0;
|
|
2641
|
|
2642 if (parseTypeSpecifier(spec))
|
|
2643 {
|
|
2644 ast->type_specifier = spec;
|
|
2645
|
|
2646 std::size_t declarator_start = token_stream.cursor();
|
|
2647
|
|
2648 DeclaratorAST *decl = 0;
|
|
2649 if (!parseDeclarator(decl))
|
|
2650 {
|
|
2651 token_stream.rewind((int) declarator_start);
|
|
2652 if (!initRequired && !parseAbstractDeclarator(decl))
|
|
2653 decl = 0;
|
|
2654 }
|
|
2655
|
|
2656 if (decl && (!initRequired || token_stream.lookAhead() == '='))
|
|
2657 {
|
|
2658 ast->declarator = decl;
|
|
2659
|
|
2660 if (token_stream.lookAhead() == '=')
|
|
2661 {
|
|
2662 token_stream.nextToken();
|
|
2663
|
|
2664 parseExpression(ast->expression);
|
|
2665 }
|
|
2666
|
|
2667 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2668 node = ast;
|
|
2669
|
|
2670 return true;
|
|
2671 }
|
|
2672 }
|
|
2673
|
|
2674 token_stream.rewind((int) start);
|
|
2675
|
|
2676 if (!parseCommaExpression(ast->expression))
|
|
2677 return false;
|
|
2678
|
|
2679 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2680 node = ast;
|
|
2681
|
|
2682 return true;
|
|
2683 }
|
|
2684
|
|
2685
|
|
2686 bool Parser::parseWhileStatement(StatementAST *&node)
|
|
2687 {
|
|
2688 std::size_t start = token_stream.cursor();
|
|
2689
|
|
2690 ADVANCE(Token_while, "while");
|
|
2691 ADVANCE('(' , "(");
|
|
2692
|
|
2693 ConditionAST *cond = 0;
|
|
2694 if (!parseCondition(cond))
|
|
2695 {
|
|
2696 reportError(("condition expected"));
|
|
2697 return false;
|
|
2698 }
|
|
2699 ADVANCE(')', ")");
|
|
2700
|
|
2701 StatementAST *body = 0;
|
|
2702 if (!parseStatement(body))
|
|
2703 {
|
|
2704 reportError(("statement expected"));
|
|
2705 return false;
|
|
2706 }
|
|
2707
|
|
2708 WhileStatementAST *ast = CreateNode<WhileStatementAST>(_M_pool);
|
|
2709 ast->condition = cond;
|
|
2710 ast->statement = body;
|
|
2711
|
|
2712 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2713 node = ast;
|
|
2714
|
|
2715 return true;
|
|
2716 }
|
|
2717
|
|
2718 bool Parser::parseDoStatement(StatementAST *&node)
|
|
2719 {
|
|
2720 std::size_t start = token_stream.cursor();
|
|
2721
|
|
2722 ADVANCE(Token_do, "do");
|
|
2723
|
|
2724 StatementAST *body = 0;
|
|
2725 if (!parseStatement(body))
|
|
2726 {
|
|
2727 reportError(("statement expected"));
|
|
2728 //return false;
|
|
2729 }
|
|
2730
|
|
2731 ADVANCE_NR(Token_while, "while");
|
|
2732 ADVANCE_NR('(' , "(");
|
|
2733
|
|
2734 ExpressionAST *expr = 0;
|
|
2735 if (!parseCommaExpression(expr))
|
|
2736 {
|
|
2737 reportError(("expression expected"));
|
|
2738 //return false;
|
|
2739 }
|
|
2740
|
|
2741 ADVANCE_NR(')', ")");
|
|
2742 ADVANCE_NR(';', ";");
|
|
2743
|
|
2744 DoStatementAST *ast = CreateNode<DoStatementAST>(_M_pool);
|
|
2745 ast->statement = body;
|
|
2746 ast->expression = expr;
|
|
2747
|
|
2748 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2749 node = ast;
|
|
2750
|
|
2751 return true;
|
|
2752 }
|
|
2753
|
|
2754 bool Parser::parseForStatement(StatementAST *&node)
|
|
2755 {
|
|
2756 std::size_t start = token_stream.cursor();
|
|
2757
|
|
2758 ADVANCE(Token_for, "for");
|
|
2759 ADVANCE('(', "(");
|
|
2760
|
|
2761 StatementAST *init = 0;
|
|
2762 if (!parseForInitStatement(init))
|
|
2763 {
|
|
2764 reportError(("for initialization expected"));
|
|
2765 return false;
|
|
2766 }
|
|
2767
|
|
2768 ConditionAST *cond = 0;
|
|
2769 parseCondition(cond);
|
|
2770 ADVANCE(';', ";");
|
|
2771
|
|
2772 ExpressionAST *expr = 0;
|
|
2773 parseCommaExpression(expr);
|
|
2774 ADVANCE(')', ")");
|
|
2775
|
|
2776 StatementAST *body = 0;
|
|
2777 if (!parseStatement(body))
|
|
2778 return false;
|
|
2779
|
|
2780 ForStatementAST *ast = CreateNode<ForStatementAST>(_M_pool);
|
|
2781 ast->init_statement = init;
|
|
2782 ast->condition = cond;
|
|
2783 ast->expression = expr;
|
|
2784 ast->statement = body;
|
|
2785
|
|
2786 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2787 node = ast;
|
|
2788
|
|
2789 return true;
|
|
2790 }
|
|
2791
|
|
2792 bool Parser::parseForInitStatement(StatementAST *&node)
|
|
2793 {
|
|
2794 if (parseDeclarationStatement(node))
|
|
2795 return true;
|
|
2796
|
|
2797 return parseExpressionStatement(node);
|
|
2798 }
|
|
2799
|
|
2800 bool Parser::parseCompoundStatement(StatementAST *&node)
|
|
2801 {
|
|
2802 std::size_t start = token_stream.cursor();
|
|
2803
|
|
2804 CHECK('{');
|
|
2805
|
|
2806 CompoundStatementAST *ast = CreateNode<CompoundStatementAST>(_M_pool);
|
|
2807
|
|
2808 while (token_stream.lookAhead())
|
|
2809 {
|
|
2810 if (token_stream.lookAhead() == '}')
|
|
2811 break;
|
|
2812
|
|
2813 std::size_t startStmt = token_stream.cursor();
|
|
2814
|
|
2815 StatementAST *stmt = 0;
|
|
2816 if (!parseStatement(stmt))
|
|
2817 {
|
|
2818 if (startStmt == token_stream.cursor())
|
|
2819 token_stream.nextToken();
|
|
2820
|
|
2821 skipUntilStatement();
|
|
2822 }
|
|
2823 else
|
|
2824 {
|
|
2825 ast->statements = snoc(ast->statements, stmt, _M_pool);
|
|
2826 }
|
|
2827 }
|
|
2828
|
|
2829 ADVANCE_NR('}', "}");
|
|
2830
|
|
2831 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2832 node = ast;
|
|
2833
|
|
2834 return true;
|
|
2835 }
|
|
2836
|
|
2837 bool Parser::parseIfStatement(StatementAST *&node)
|
|
2838 {
|
|
2839 std::size_t start = token_stream.cursor();
|
|
2840
|
|
2841 ADVANCE(Token_if, "if");
|
|
2842
|
|
2843 ADVANCE('(' , "(");
|
|
2844
|
|
2845 IfStatementAST *ast = CreateNode<IfStatementAST>(_M_pool);
|
|
2846
|
|
2847 ConditionAST *cond = 0;
|
|
2848 if (!parseCondition(cond))
|
|
2849 {
|
|
2850 reportError(("condition expected"));
|
|
2851 return false;
|
|
2852 }
|
|
2853 ADVANCE(')', ")");
|
|
2854
|
|
2855 StatementAST *stmt = 0;
|
|
2856 if (!parseStatement(stmt))
|
|
2857 {
|
|
2858 reportError(("statement expected"));
|
|
2859 return false;
|
|
2860 }
|
|
2861
|
|
2862 ast->condition = cond;
|
|
2863 ast->statement = stmt;
|
|
2864
|
|
2865 if (token_stream.lookAhead() == Token_else)
|
|
2866 {
|
|
2867 token_stream.nextToken();
|
|
2868
|
|
2869 if (!parseStatement(ast->else_statement))
|
|
2870 {
|
|
2871 reportError(("statement expected"));
|
|
2872 return false;
|
|
2873 }
|
|
2874 }
|
|
2875
|
|
2876 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2877 node = ast;
|
|
2878
|
|
2879 return true;
|
|
2880 }
|
|
2881
|
|
2882 bool Parser::parseSwitchStatement(StatementAST *&node)
|
|
2883 {
|
|
2884 std::size_t start = token_stream.cursor();
|
|
2885 ADVANCE(Token_switch, "switch");
|
|
2886
|
|
2887 ADVANCE('(' , "(");
|
|
2888
|
|
2889 ConditionAST *cond = 0;
|
|
2890 if (!parseCondition(cond))
|
|
2891 {
|
|
2892 reportError(("condition expected"));
|
|
2893 return false;
|
|
2894 }
|
|
2895 ADVANCE(')', ")");
|
|
2896
|
|
2897 StatementAST *stmt = 0;
|
|
2898 if (!parseCompoundStatement(stmt))
|
|
2899 {
|
|
2900 syntaxError();
|
|
2901 return false;
|
|
2902 }
|
|
2903
|
|
2904 SwitchStatementAST *ast = CreateNode<SwitchStatementAST>(_M_pool);
|
|
2905 ast->condition = cond;
|
|
2906 ast->statement = stmt;
|
|
2907
|
|
2908 UPDATE_POS(ast, start, token_stream.cursor());
|
|
2909 node = ast;
|
|
2910
|
|
2911 return true;
|
|
2912 }
|
|
2913
|
|
2914 bool Parser::parseLabeledStatement(StatementAST *&node)
|
|
2915 {
|
|
2916 switch(token_stream.lookAhead())
|
|
2917 {
|
|
2918 case Token_identifier:
|
|
2919 case Token_default:
|
|
2920 if (token_stream.lookAhead(1) == ':')
|
|
2921 {
|
|
2922 token_stream.nextToken();
|
|
2923 token_stream.nextToken();
|
|
2924
|
|
2925 StatementAST *stmt = 0;
|
|
2926 if (parseStatement(stmt))
|
|
2927 {
|
|
2928 node = stmt;
|
|
2929 return true;
|
|
2930 }
|
|
2931 }
|
|
2932 break;
|
|
2933
|
|
2934 case Token_case:
|
|
2935 {
|
|
2936 token_stream.nextToken();
|
|
2937 ExpressionAST *expr = 0;
|
|
2938 if (!parseConstantExpression(expr))
|
|
2939 {
|
|
2940 reportError(("expression expected"));
|
|
2941 }
|
|
2942 else if (token_stream.lookAhead() == Token_ellipsis)
|
|
2943 {
|
|
2944 token_stream.nextToken();
|
|
2945
|
|
2946 ExpressionAST *expr2 = 0;
|
|
2947 if (!parseConstantExpression(expr2))
|
|
2948 {
|
|
2949 reportError(("expression expected"));
|
|
2950 }
|
|
2951 }
|
|
2952 ADVANCE(':', ":");
|
|
2953
|
|
2954 StatementAST *stmt = 0;
|
|
2955 if (parseStatement(stmt))
|
|
2956 {
|
|
2957 node = stmt;
|
|
2958 return true;
|
|
2959 }
|
|
2960 }
|
|
2961 break;
|
|
2962
|
|
2963 }
|
|
2964
|
|
2965 return false;
|
|
2966 }
|
|
2967
|
|
2968 bool Parser::parseBlockDeclaration(DeclarationAST *&node)
|
|
2969 {
|
|
2970 switch(token_stream.lookAhead())
|
|
2971 {
|
|
2972 case Token_typedef:
|
|
2973 return parseTypedef(node);
|
|
2974 case Token_using:
|
|
2975 return parseUsing(node);
|
|
2976 case Token_asm:
|
|
2977 return parseAsmDefinition(node);
|
|
2978 case Token_namespace:
|
|
2979 return parseNamespaceAliasDefinition(node);
|
|
2980 }
|
|
2981
|
|
2982 std::size_t start = token_stream.cursor();
|
|
2983
|
|
2984 const ListNode<std::size_t> *cv = 0;
|
|
2985 parseCvQualify(cv);
|
|
2986
|
|
2987 const ListNode<std::size_t> *storageSpec = 0;
|
|
2988 parseStorageClassSpecifier(storageSpec);
|
|
2989
|
|
2990 parseCvQualify(cv);
|
|
2991
|
|
2992 TypeSpecifierAST *spec = 0;
|
|
2993 if (!parseTypeSpecifierOrClassSpec(spec))
|
|
2994 { // replace with simpleTypeSpecifier?!?!
|
|
2995 token_stream.rewind((int) start);
|
|
2996 return false;
|
|
2997 }
|
|
2998
|
|
2999 parseCvQualify(cv);
|
|
3000 spec->cv = cv;
|
|
3001
|
|
3002 const ListNode<InitDeclaratorAST*> *declarators = 0;
|
|
3003 parseInitDeclaratorList(declarators);
|
|
3004
|
|
3005 if (token_stream.lookAhead() != ';')
|
|
3006 {
|
|
3007 token_stream.rewind((int) start);
|
|
3008 return false;
|
|
3009 }
|
|
3010 token_stream.nextToken();
|
|
3011
|
|
3012 SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool);
|
|
3013 ast->type_specifier = spec;
|
|
3014 ast->init_declarators = declarators;
|
|
3015
|
|
3016 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3017 node = ast;
|
|
3018
|
|
3019 return true;
|
|
3020 }
|
|
3021
|
|
3022 bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node)
|
|
3023 {
|
|
3024 std::size_t start = token_stream.cursor();
|
|
3025
|
|
3026 CHECK(Token_namespace);
|
|
3027
|
|
3028 NamespaceAliasDefinitionAST *ast
|
|
3029 = CreateNode<NamespaceAliasDefinitionAST>(_M_pool);
|
|
3030
|
|
3031 ADVANCE(Token_identifier, "identifier");
|
|
3032 ast->namespace_name = token_stream.cursor() - 1;
|
|
3033
|
|
3034 ADVANCE('=', "=");
|
|
3035
|
|
3036 if (!parseName(ast->alias_name))
|
|
3037 {
|
|
3038 reportError(("Namespace name expected"));
|
|
3039 }
|
|
3040
|
|
3041 ADVANCE(';', ";");
|
|
3042
|
|
3043 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3044 node = ast;
|
|
3045
|
|
3046 return true;
|
|
3047 }
|
|
3048
|
|
3049 bool Parser::parseDeclarationStatement(StatementAST *&node)
|
|
3050 {
|
|
3051 std::size_t start = token_stream.cursor();
|
|
3052
|
|
3053 DeclarationAST *decl = 0;
|
|
3054 if (!parseBlockDeclaration(decl))
|
|
3055 return false;
|
|
3056
|
|
3057 DeclarationStatementAST *ast = CreateNode<DeclarationStatementAST>(_M_pool);
|
|
3058 ast->declaration = decl;
|
|
3059
|
|
3060 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3061 node = ast;
|
|
3062
|
|
3063 return true;
|
|
3064 }
|
|
3065
|
|
3066 bool Parser::parseDeclarationInternal(DeclarationAST *&node)
|
|
3067 {
|
|
3068 std::size_t start = token_stream.cursor();
|
|
3069
|
|
3070 // that is for the case '__declspec(dllexport) int ...' or
|
|
3071 // '__declspec(dllexport) inline int ...', etc.
|
|
3072 WinDeclSpecAST *winDeclSpec = 0;
|
|
3073 parseWinDeclSpec(winDeclSpec);
|
|
3074
|
|
3075 const ListNode<std::size_t> *funSpec = 0;
|
|
3076 bool hasFunSpec = parseFunctionSpecifier(funSpec);
|
|
3077
|
|
3078 const ListNode<std::size_t> *cv = 0;
|
|
3079 parseCvQualify(cv);
|
|
3080
|
|
3081 const ListNode<std::size_t> *storageSpec = 0;
|
|
3082 bool hasStorageSpec = parseStorageClassSpecifier(storageSpec);
|
|
3083
|
|
3084 if (hasStorageSpec && !hasFunSpec)
|
|
3085 hasFunSpec = parseFunctionSpecifier(funSpec);
|
|
3086
|
|
3087 // that is for the case 'friend __declspec(dllexport) ....'
|
|
3088 parseWinDeclSpec(winDeclSpec);
|
|
3089
|
|
3090 if (!cv)
|
|
3091 parseCvQualify(cv);
|
|
3092
|
|
3093 int index = (int) token_stream.cursor();
|
|
3094 NameAST *name = 0;
|
|
3095 if (parseName(name, true) && token_stream.lookAhead() == '(')
|
|
3096 {
|
|
3097 // no type specifier, maybe a constructor or a cast operator??
|
|
3098
|
|
3099 token_stream.rewind((int) index);
|
|
3100
|
|
3101 InitDeclaratorAST *declarator = 0;
|
|
3102 if (parseInitDeclarator(declarator))
|
|
3103 {
|
|
3104 switch(token_stream.lookAhead())
|
|
3105 {
|
|
3106 case ';':
|
|
3107 {
|
|
3108 token_stream.nextToken();
|
|
3109
|
|
3110 SimpleDeclarationAST *ast
|
|
3111 = CreateNode<SimpleDeclarationAST>(_M_pool);
|
|
3112
|
|
3113 ast->storage_specifiers = storageSpec;
|
|
3114 ast->function_specifiers = funSpec;
|
|
3115 ast->init_declarators = snoc(ast->init_declarators,
|
|
3116 declarator, _M_pool);
|
|
3117
|
|
3118 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3119 node = ast;
|
|
3120 }
|
|
3121 return true;
|
|
3122
|
|
3123 case ':':
|
|
3124 {
|
|
3125 CtorInitializerAST *ctorInit = 0;
|
|
3126 StatementAST *funBody = 0;
|
|
3127
|
|
3128 if (parseCtorInitializer(ctorInit)
|
|
3129 && parseFunctionBody(funBody))
|
|
3130 {
|
|
3131 FunctionDefinitionAST *ast
|
|
3132 = CreateNode<FunctionDefinitionAST>(_M_pool);
|
|
3133
|
|
3134 ast->storage_specifiers = storageSpec;
|
|
3135 ast->function_specifiers = funSpec;
|
|
3136 ast->init_declarator = declarator;
|
|
3137 ast->function_body = funBody;
|
|
3138
|
|
3139 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3140 node = ast;
|
|
3141
|
|
3142 return true;
|
|
3143 }
|
|
3144 }
|
|
3145 break;
|
|
3146
|
|
3147 case '{':
|
|
3148 {
|
|
3149 StatementAST *funBody = 0;
|
|
3150 if (parseFunctionBody(funBody))
|
|
3151 {
|
|
3152 FunctionDefinitionAST *ast
|
|
3153 = CreateNode<FunctionDefinitionAST>(_M_pool);
|
|
3154
|
|
3155 ast->storage_specifiers = storageSpec;
|
|
3156 ast->function_specifiers = funSpec;
|
|
3157 ast->init_declarator = declarator;
|
|
3158 ast->function_body = funBody;
|
|
3159
|
|
3160 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3161 node = ast;
|
|
3162
|
|
3163 return true;
|
|
3164 }
|
|
3165 }
|
|
3166 break;
|
|
3167
|
|
3168 case '(':
|
|
3169 case '[':
|
|
3170 // ops!! it seems a declarator
|
|
3171 goto start_decl;
|
|
3172 break;
|
|
3173 }
|
|
3174
|
|
3175 }
|
|
3176 }
|
|
3177
|
|
3178 start_decl:
|
|
3179 token_stream.rewind((int) index);
|
|
3180
|
|
3181 if (token_stream.lookAhead() == Token_const
|
|
3182 && token_stream.lookAhead(1) == Token_identifier
|
|
3183 && token_stream.lookAhead(2) == '=')
|
|
3184 {
|
|
3185 // constant definition
|
|
3186 token_stream.nextToken(); // skip const
|
|
3187
|
|
3188 const ListNode<InitDeclaratorAST*> *declarators = 0;
|
|
3189 if (!parseInitDeclaratorList(declarators))
|
|
3190 {
|
|
3191 syntaxError();
|
|
3192 return false;
|
|
3193 }
|
|
3194
|
|
3195 ADVANCE(';', ";");
|
|
3196
|
|
3197 #if defined(__GNUC__)
|
|
3198 #warning "mark the ast as constant"
|
|
3199 #endif
|
|
3200 SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool);
|
|
3201 ast->init_declarators = declarators;
|
|
3202
|
|
3203 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3204 node = ast;
|
|
3205
|
|
3206 return true;
|
|
3207 }
|
|
3208
|
|
3209 TypeSpecifierAST *spec = 0;
|
|
3210 if (parseTypeSpecifier(spec))
|
|
3211 {
|
|
3212 Q_ASSERT(spec != 0);
|
|
3213
|
|
3214 if (!hasFunSpec)
|
|
3215 parseFunctionSpecifier(funSpec); // e.g. "void inline"
|
|
3216
|
|
3217 spec->cv = cv;
|
|
3218
|
|
3219 const ListNode<InitDeclaratorAST*> *declarators = 0;
|
|
3220 InitDeclaratorAST *decl = 0;
|
|
3221 int startDeclarator = (int) token_stream.cursor();
|
|
3222 bool maybeFunctionDefinition = false;
|
|
3223
|
|
3224 if (token_stream.lookAhead() != ';')
|
|
3225 {
|
|
3226 if (parseInitDeclarator(decl) && token_stream.lookAhead() == '{')
|
|
3227 {
|
|
3228 // function definition
|
|
3229 maybeFunctionDefinition = true;
|
|
3230 }
|
|
3231 else
|
|
3232 {
|
|
3233 token_stream.rewind((int) startDeclarator);
|
|
3234 if (!parseInitDeclaratorList(declarators))
|
|
3235 {
|
|
3236 syntaxError();
|
|
3237 return false;
|
|
3238 }
|
|
3239 }
|
|
3240 }
|
|
3241
|
|
3242 switch(token_stream.lookAhead())
|
|
3243 {
|
|
3244 case ';':
|
|
3245 {
|
|
3246 token_stream.nextToken();
|
|
3247 SimpleDeclarationAST *ast
|
|
3248 = CreateNode<SimpleDeclarationAST>(_M_pool);
|
|
3249
|
|
3250 ast->storage_specifiers = storageSpec;
|
|
3251 ast->function_specifiers = funSpec;
|
|
3252 ast->type_specifier = spec;
|
|
3253 ast->win_decl_specifiers = winDeclSpec;
|
|
3254 ast->init_declarators = declarators;
|
|
3255
|
|
3256 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3257 node = ast;
|
|
3258 }
|
|
3259 return true;
|
|
3260
|
|
3261 case '{':
|
|
3262 {
|
|
3263 if (!maybeFunctionDefinition)
|
|
3264 {
|
|
3265 syntaxError();
|
|
3266 return false;
|
|
3267 }
|
|
3268
|
|
3269 StatementAST *funBody = 0;
|
|
3270 if (parseFunctionBody(funBody))
|
|
3271 {
|
|
3272 FunctionDefinitionAST *ast
|
|
3273 = CreateNode<FunctionDefinitionAST>(_M_pool);
|
|
3274
|
|
3275 ast->win_decl_specifiers = winDeclSpec;
|
|
3276 ast->storage_specifiers = storageSpec;
|
|
3277 ast->function_specifiers = funSpec;
|
|
3278 ast->type_specifier = spec;
|
|
3279 ast->init_declarator = decl;
|
|
3280 ast->function_body = funBody;
|
|
3281
|
|
3282 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3283 node = ast;
|
|
3284
|
|
3285 return true;
|
|
3286 }
|
|
3287 }
|
|
3288 break;
|
|
3289 } // end switch
|
|
3290 }
|
|
3291
|
|
3292 syntaxError();
|
|
3293 return false;
|
|
3294 }
|
|
3295
|
|
3296 bool Parser::skipFunctionBody(StatementAST *&)
|
|
3297 {
|
|
3298 #if defined(__GNUC__)
|
|
3299 #warning "Parser::skipFunctionBody() -- implement me"
|
|
3300 #endif
|
|
3301 Q_ASSERT(0); // ### not implemented
|
|
3302 return 0;
|
|
3303 }
|
|
3304
|
|
3305 bool Parser::parseFunctionBody(StatementAST *&node)
|
|
3306 {
|
|
3307 if (control->skipFunctionBody())
|
|
3308 return skipFunctionBody(node);
|
|
3309
|
|
3310 return parseCompoundStatement(node);
|
|
3311 }
|
|
3312
|
|
3313 bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node)
|
|
3314 {
|
|
3315 if (parseClassSpecifier(node))
|
|
3316 return true;
|
|
3317 else if (parseEnumSpecifier(node))
|
|
3318 return true;
|
|
3319 else if (parseTypeSpecifier(node))
|
|
3320 return true;
|
|
3321
|
|
3322 return false;
|
|
3323 }
|
|
3324
|
|
3325 bool Parser::parseTryBlockStatement(StatementAST *&node)
|
|
3326 {
|
|
3327 #if defined(__GNUC__)
|
|
3328 #warning "implement me"
|
|
3329 #endif
|
|
3330 CHECK(Token_try);
|
|
3331
|
|
3332 StatementAST *stmt = 0;
|
|
3333 if (!parseCompoundStatement(stmt))
|
|
3334 {
|
|
3335 syntaxError();
|
|
3336 return false;
|
|
3337 }
|
|
3338
|
|
3339 if (token_stream.lookAhead() != Token_catch)
|
|
3340 {
|
|
3341 reportError(("catch expected"));
|
|
3342 return false;
|
|
3343 }
|
|
3344
|
|
3345 while (token_stream.lookAhead() == Token_catch)
|
|
3346 {
|
|
3347 token_stream.nextToken();
|
|
3348 ADVANCE('(', "(");
|
|
3349 ConditionAST *cond = 0;
|
|
3350 if (token_stream.lookAhead() == Token_ellipsis)
|
|
3351 {
|
|
3352 token_stream.nextToken();
|
|
3353 }
|
|
3354 else if (!parseCondition(cond, false))
|
|
3355 {
|
|
3356 reportError(("condition expected"));
|
|
3357 return false;
|
|
3358 }
|
|
3359 ADVANCE(')', ")");
|
|
3360
|
|
3361 StatementAST *body = 0;
|
|
3362 if (!parseCompoundStatement(body))
|
|
3363 {
|
|
3364 syntaxError();
|
|
3365 return false;
|
|
3366 }
|
|
3367 }
|
|
3368
|
|
3369 node = stmt;
|
|
3370 return true;
|
|
3371 }
|
|
3372
|
|
3373 bool Parser::parsePrimaryExpression(ExpressionAST *&node)
|
|
3374 {
|
|
3375 std::size_t start = token_stream.cursor();
|
|
3376
|
|
3377 PrimaryExpressionAST *ast = CreateNode<PrimaryExpressionAST>(_M_pool);
|
|
3378
|
|
3379 switch(token_stream.lookAhead())
|
|
3380 {
|
|
3381 case Token_string_literal:
|
|
3382 parseStringLiteral(ast->literal);
|
|
3383 break;
|
|
3384
|
|
3385 case Token_number_literal:
|
|
3386 case Token_char_literal:
|
|
3387 case Token_true:
|
|
3388 case Token_false:
|
|
3389 case Token_this:
|
|
3390 ast->token = token_stream.cursor();
|
|
3391 token_stream.nextToken();
|
|
3392 break;
|
|
3393
|
|
3394 case '(':
|
|
3395 token_stream.nextToken();
|
|
3396
|
|
3397 if (token_stream.lookAhead() == '{')
|
|
3398 {
|
|
3399 if (!parseCompoundStatement(ast->expression_statement))
|
|
3400 return false;
|
|
3401 }
|
|
3402 else
|
|
3403 {
|
|
3404 if (!parseExpression(ast->sub_expression))
|
|
3405 return false;
|
|
3406 }
|
|
3407
|
|
3408 CHECK(')');
|
|
3409 break;
|
|
3410
|
|
3411 default:
|
|
3412 if (!parseName(ast->name))
|
|
3413 return false;
|
|
3414
|
|
3415 break;
|
|
3416 }
|
|
3417
|
|
3418 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3419 node = ast;
|
|
3420
|
|
3421 return true;
|
|
3422 }
|
|
3423
|
|
3424
|
|
3425 /*
|
|
3426 postfix-expression-internal:
|
|
3427 [ expression ]
|
|
3428 ( expression-list [opt] )
|
|
3429 (.|->) template [opt] id-expression
|
|
3430 (.|->) pseudo-destructor-name
|
|
3431 ++
|
|
3432 --
|
|
3433 */
|
|
3434 bool Parser::parsePostfixExpressionInternal(ExpressionAST *&node)
|
|
3435 {
|
|
3436 std::size_t start = token_stream.cursor();
|
|
3437
|
|
3438 switch (token_stream.lookAhead())
|
|
3439 {
|
|
3440 case '[':
|
|
3441 {
|
|
3442 token_stream.nextToken();
|
|
3443 ExpressionAST *expr = 0;
|
|
3444 parseExpression(expr);
|
|
3445 CHECK(']');
|
|
3446
|
|
3447 SubscriptExpressionAST *ast
|
|
3448 = CreateNode<SubscriptExpressionAST>(_M_pool);
|
|
3449
|
|
3450 ast->subscript = expr;
|
|
3451
|
|
3452 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3453 node = ast;
|
|
3454 }
|
|
3455 return true;
|
|
3456
|
|
3457 case '(':
|
|
3458 {
|
|
3459 token_stream.nextToken();
|
|
3460 ExpressionAST *expr = 0;
|
|
3461 parseExpression(expr);
|
|
3462 CHECK(')');
|
|
3463
|
|
3464 FunctionCallAST *ast = CreateNode<FunctionCallAST>(_M_pool);
|
|
3465 ast->arguments = expr;
|
|
3466
|
|
3467 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3468 node = ast;
|
|
3469 }
|
|
3470 return true;
|
|
3471
|
|
3472 case '.':
|
|
3473 case Token_arrow:
|
|
3474 {
|
|
3475 std::size_t op = token_stream.cursor();
|
|
3476 token_stream.nextToken();
|
|
3477
|
|
3478 std::size_t templ = 0;
|
|
3479 if (token_stream.lookAhead() == Token_template)
|
|
3480 {
|
|
3481 templ = token_stream.cursor();
|
|
3482 token_stream.nextToken();
|
|
3483 }
|
|
3484
|
|
3485 int saved = int(token_stream.cursor());
|
|
3486 NameAST *name = 0;
|
|
3487
|
|
3488 if (parseName(name, true) && name->unqualified_name
|
|
3489 && name->unqualified_name->template_arguments != 0
|
|
3490 && token_stream.lookAhead() == '(') {
|
|
3491 // a template method call
|
|
3492 // ### reverse the logic
|
|
3493 } else {
|
|
3494 token_stream.rewind(saved);
|
|
3495 name = 0;
|
|
3496
|
|
3497 if (! parseName (name, templ != 0))
|
|
3498 return false;
|
|
3499 }
|
|
3500
|
|
3501 ClassMemberAccessAST *ast = CreateNode<ClassMemberAccessAST>(_M_pool);
|
|
3502 ast->op = op;
|
|
3503 ast->name = name;
|
|
3504
|
|
3505 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3506 node = ast;
|
|
3507 }
|
|
3508 return true;
|
|
3509
|
|
3510 case Token_incr:
|
|
3511 case Token_decr:
|
|
3512 {
|
|
3513 std::size_t op = token_stream.cursor();
|
|
3514 token_stream.nextToken();
|
|
3515
|
|
3516 IncrDecrExpressionAST *ast = CreateNode<IncrDecrExpressionAST>(_M_pool);
|
|
3517 ast->op = op;
|
|
3518
|
|
3519 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3520 node = ast;
|
|
3521 }
|
|
3522 return true;
|
|
3523
|
|
3524 default:
|
|
3525 return false;
|
|
3526 }
|
|
3527 }
|
|
3528
|
|
3529 /*
|
|
3530 postfix-expression:
|
|
3531 simple-type-specifier ( expression-list [opt] )
|
|
3532 primary-expression postfix-expression-internal*
|
|
3533 */
|
|
3534 bool Parser::parsePostfixExpression(ExpressionAST *&node)
|
|
3535 {
|
|
3536 std::size_t start = token_stream.cursor();
|
|
3537
|
|
3538 switch (token_stream.lookAhead())
|
|
3539 {
|
|
3540 case Token_dynamic_cast:
|
|
3541 case Token_static_cast:
|
|
3542 case Token_reinterpret_cast:
|
|
3543 case Token_const_cast:
|
|
3544 {
|
|
3545 std::size_t castOp = token_stream.cursor();
|
|
3546 token_stream.nextToken();
|
|
3547
|
|
3548 CHECK('<');
|
|
3549 TypeIdAST *typeId = 0;
|
|
3550 parseTypeId(typeId);
|
|
3551 CHECK('>');
|
|
3552
|
|
3553 CHECK('(');
|
|
3554 ExpressionAST *expr = 0;
|
|
3555 parseCommaExpression(expr);
|
|
3556 CHECK(')');
|
|
3557
|
|
3558 CppCastExpressionAST *ast = CreateNode<CppCastExpressionAST>(_M_pool);
|
|
3559 ast->op = castOp;
|
|
3560 ast->type_id = typeId;
|
|
3561 ast->expression = expr;
|
|
3562
|
|
3563 ExpressionAST *e = 0;
|
|
3564 while (parsePostfixExpressionInternal(e))
|
|
3565 {
|
|
3566 ast->sub_expressions = snoc(ast->sub_expressions, e, _M_pool);
|
|
3567 }
|
|
3568
|
|
3569 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3570 node = ast;
|
|
3571 }
|
|
3572 return true;
|
|
3573
|
|
3574 case Token_typename:
|
|
3575 {
|
|
3576 std::size_t token = token_stream.cursor();
|
|
3577 token_stream.nextToken();
|
|
3578
|
|
3579 NameAST* name = 0;
|
|
3580 if (!parseName(name, true))
|
|
3581 return false;
|
|
3582
|
|
3583 CHECK('(');
|
|
3584 ExpressionAST *expr = 0;
|
|
3585 parseCommaExpression(expr);
|
|
3586 CHECK(')');
|
|
3587
|
|
3588 TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(_M_pool);
|
|
3589 ast->typename_token = token;
|
|
3590 ast->name = name;
|
|
3591 ast->expression = expr;
|
|
3592
|
|
3593 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3594 node = ast;
|
|
3595 }
|
|
3596 return true;
|
|
3597
|
|
3598 case Token_typeid:
|
|
3599 {
|
|
3600 token_stream.nextToken();
|
|
3601
|
|
3602 CHECK('(');
|
|
3603 TypeIdAST *typeId = 0;
|
|
3604 parseTypeId(typeId);
|
|
3605 CHECK(')');
|
|
3606
|
|
3607 TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(_M_pool);
|
|
3608 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3609 node = ast;
|
|
3610 }
|
|
3611 return true;
|
|
3612
|
|
3613 default:
|
|
3614 break;
|
|
3615 }
|
|
3616
|
|
3617 std::size_t saved_pos = token_stream.cursor();
|
|
3618
|
|
3619 TypeSpecifierAST *typeSpec = 0;
|
|
3620 ExpressionAST *expr = 0;
|
|
3621
|
|
3622 // let's try to parse a type
|
|
3623 NameAST *name = 0;
|
|
3624 if (parseName(name, true))
|
|
3625 {
|
|
3626 Q_ASSERT(name->unqualified_name != 0);
|
|
3627
|
|
3628 bool has_template_args
|
|
3629 = name->unqualified_name->template_arguments != 0;
|
|
3630
|
|
3631 if (has_template_args && token_stream.lookAhead() == '(')
|
|
3632 {
|
|
3633 ExpressionAST *cast_expr = 0;
|
|
3634 if (parseCastExpression(cast_expr)
|
|
3635 && cast_expr->kind == AST::Kind_CastExpression)
|
|
3636 {
|
|
3637 token_stream.rewind((int) saved_pos);
|
|
3638 parsePrimaryExpression(expr);
|
|
3639 goto L_no_rewind;
|
|
3640 }
|
|
3641 }
|
|
3642 }
|
|
3643
|
|
3644 token_stream.rewind((int) saved_pos);
|
|
3645
|
|
3646 L_no_rewind:
|
|
3647 if (!expr && parseSimpleTypeSpecifier(typeSpec)
|
|
3648 && token_stream.lookAhead() == '(')
|
|
3649 {
|
|
3650 token_stream.nextToken(); // skip '('
|
|
3651 parseCommaExpression(expr);
|
|
3652 CHECK(')');
|
|
3653 }
|
|
3654 else if (expr)
|
|
3655 {
|
|
3656 typeSpec = 0;
|
|
3657 }
|
|
3658 else
|
|
3659 {
|
|
3660 typeSpec = 0;
|
|
3661 token_stream.rewind((int) start);
|
|
3662
|
|
3663 if (!parsePrimaryExpression(expr))
|
|
3664 return false;
|
|
3665 }
|
|
3666
|
|
3667 const ListNode<ExpressionAST*> *sub_expressions = 0;
|
|
3668 ExpressionAST *sub_expression = 0;
|
|
3669
|
|
3670 while (parsePostfixExpressionInternal(sub_expression))
|
|
3671 sub_expressions = snoc(sub_expressions, sub_expression, _M_pool);
|
|
3672
|
|
3673 if (sub_expressions || ! expr || (typeSpec && expr))
|
|
3674 {
|
|
3675 PostfixExpressionAST *ast = CreateNode<PostfixExpressionAST>(_M_pool);
|
|
3676 ast->type_specifier = typeSpec;
|
|
3677 ast->expression = expr;
|
|
3678 ast->sub_expressions = sub_expressions;
|
|
3679
|
|
3680 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3681 node = ast;
|
|
3682 }
|
|
3683 else
|
|
3684 node = expr;
|
|
3685
|
|
3686 return true;
|
|
3687 }
|
|
3688
|
|
3689 bool Parser::parseUnaryExpression(ExpressionAST *&node)
|
|
3690 {
|
|
3691 std::size_t start = token_stream.cursor();
|
|
3692
|
|
3693 switch(token_stream.lookAhead())
|
|
3694 {
|
|
3695 case Token_incr:
|
|
3696 case Token_decr:
|
|
3697 case '*':
|
|
3698 case '&':
|
|
3699 case '+':
|
|
3700 case '-':
|
|
3701 case '!':
|
|
3702 case '~':
|
|
3703 {
|
|
3704 std::size_t op = token_stream.cursor();
|
|
3705 token_stream.nextToken();
|
|
3706
|
|
3707 ExpressionAST *expr = 0;
|
|
3708 if (!parseCastExpression(expr))
|
|
3709 return false;
|
|
3710
|
|
3711 UnaryExpressionAST *ast = CreateNode<UnaryExpressionAST>(_M_pool);
|
|
3712 ast->op = op;
|
|
3713 ast->expression = expr;
|
|
3714
|
|
3715 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3716 node = ast;
|
|
3717 }
|
|
3718 return true;
|
|
3719
|
|
3720 case Token_sizeof:
|
|
3721 {
|
|
3722 std::size_t sizeof_token = token_stream.cursor();
|
|
3723 token_stream.nextToken();
|
|
3724
|
|
3725 SizeofExpressionAST *ast = CreateNode<SizeofExpressionAST>(_M_pool);
|
|
3726 ast->sizeof_token = sizeof_token;
|
|
3727
|
|
3728 std::size_t index = token_stream.cursor();
|
|
3729 if (token_stream.lookAhead() == '(')
|
|
3730 {
|
|
3731 token_stream.nextToken();
|
|
3732 if (parseTypeId(ast->type_id) && token_stream.lookAhead() == ')')
|
|
3733 {
|
|
3734 token_stream.nextToken(); // skip )
|
|
3735
|
|
3736 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3737 node = ast;
|
|
3738 return true;
|
|
3739 }
|
|
3740
|
|
3741 ast->type_id = 0;
|
|
3742 token_stream.rewind((int) index);
|
|
3743 }
|
|
3744
|
|
3745 if (!parseUnaryExpression(ast->expression))
|
|
3746 return false;
|
|
3747
|
|
3748 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3749 node = ast;
|
|
3750 return true;
|
|
3751 }
|
|
3752
|
|
3753 default:
|
|
3754 break;
|
|
3755 }
|
|
3756
|
|
3757 int token = token_stream.lookAhead();
|
|
3758
|
|
3759 if (token == Token_new
|
|
3760 || (token == Token_scope && token_stream.lookAhead(1) == Token_new))
|
|
3761 return parseNewExpression(node);
|
|
3762
|
|
3763 if (token == Token_delete
|
|
3764 || (token == Token_scope && token_stream.lookAhead(1) == Token_delete))
|
|
3765 return parseDeleteExpression(node);
|
|
3766
|
|
3767 return parsePostfixExpression(node);
|
|
3768 }
|
|
3769
|
|
3770 bool Parser::parseNewExpression(ExpressionAST *&node)
|
|
3771 {
|
|
3772 std::size_t start = token_stream.cursor();
|
|
3773
|
|
3774 NewExpressionAST *ast = CreateNode<NewExpressionAST>(_M_pool);
|
|
3775
|
|
3776 if (token_stream.lookAhead() == Token_scope
|
|
3777 && token_stream.lookAhead(1) == Token_new)
|
|
3778 {
|
|
3779 ast->scope_token = token_stream.cursor();
|
|
3780 token_stream.nextToken();
|
|
3781 }
|
|
3782
|
|
3783 CHECK(Token_new);
|
|
3784 ast->new_token = token_stream.cursor() - 1;
|
|
3785
|
|
3786 if (token_stream.lookAhead() == '(')
|
|
3787 {
|
|
3788 token_stream.nextToken();
|
|
3789 parseCommaExpression(ast->expression);
|
|
3790 CHECK(')');
|
|
3791 }
|
|
3792
|
|
3793 if (token_stream.lookAhead() == '(')
|
|
3794 {
|
|
3795 token_stream.nextToken();
|
|
3796 parseTypeId(ast->type_id);
|
|
3797 CHECK(')');
|
|
3798 }
|
|
3799 else
|
|
3800 {
|
|
3801 parseNewTypeId(ast->new_type_id);
|
|
3802 }
|
|
3803
|
|
3804 parseNewInitializer(ast->new_initializer);
|
|
3805
|
|
3806 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3807 node = ast;
|
|
3808
|
|
3809 return true;
|
|
3810 }
|
|
3811
|
|
3812 bool Parser::parseNewTypeId(NewTypeIdAST *&node)
|
|
3813 {
|
|
3814 std::size_t start = token_stream.cursor();
|
|
3815
|
|
3816 TypeSpecifierAST *typeSpec = 0;
|
|
3817 if (!parseTypeSpecifier(typeSpec))
|
|
3818 return false;
|
|
3819
|
|
3820 NewTypeIdAST *ast = CreateNode<NewTypeIdAST>(_M_pool);
|
|
3821 ast->type_specifier = typeSpec;
|
|
3822
|
|
3823 parseNewDeclarator(ast->new_declarator);
|
|
3824
|
|
3825 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3826 node = ast;
|
|
3827
|
|
3828 return true;
|
|
3829 }
|
|
3830
|
|
3831 bool Parser::parseNewDeclarator(NewDeclaratorAST *&node)
|
|
3832 {
|
|
3833 std::size_t start = token_stream.cursor();
|
|
3834
|
|
3835 NewDeclaratorAST *ast = CreateNode<NewDeclaratorAST>(_M_pool);
|
|
3836
|
|
3837 PtrOperatorAST *ptrOp = 0;
|
|
3838 if (parsePtrOperator(ptrOp))
|
|
3839 {
|
|
3840 ast->ptr_op = ptrOp;
|
|
3841 parseNewDeclarator(ast->sub_declarator);
|
|
3842 }
|
|
3843
|
|
3844 while (token_stream.lookAhead() == '[')
|
|
3845 {
|
|
3846 token_stream.nextToken();
|
|
3847 ExpressionAST *expr = 0;
|
|
3848 parseExpression(expr);
|
|
3849 ast->expressions = snoc(ast->expressions, expr, _M_pool);
|
|
3850 ADVANCE(']', "]");
|
|
3851 }
|
|
3852
|
|
3853 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3854 node = ast;
|
|
3855
|
|
3856 return true;
|
|
3857 }
|
|
3858
|
|
3859 bool Parser::parseNewInitializer(NewInitializerAST *&node)
|
|
3860 {
|
|
3861 std::size_t start = token_stream.cursor();
|
|
3862
|
|
3863 CHECK('(');
|
|
3864
|
|
3865 NewInitializerAST *ast = CreateNode<NewInitializerAST>(_M_pool);
|
|
3866
|
|
3867 parseCommaExpression(ast->expression);
|
|
3868
|
|
3869 CHECK(')');
|
|
3870
|
|
3871 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3872 node = ast;
|
|
3873
|
|
3874 return true;
|
|
3875 }
|
|
3876
|
|
3877 bool Parser::parseDeleteExpression(ExpressionAST *&node)
|
|
3878 {
|
|
3879 std::size_t start = token_stream.cursor();
|
|
3880
|
|
3881 DeleteExpressionAST *ast = CreateNode<DeleteExpressionAST>(_M_pool);
|
|
3882
|
|
3883 if (token_stream.lookAhead() == Token_scope
|
|
3884 && token_stream.lookAhead(1) == Token_delete)
|
|
3885 {
|
|
3886 ast->scope_token = token_stream.cursor();
|
|
3887 token_stream.nextToken();
|
|
3888 }
|
|
3889
|
|
3890 CHECK(Token_delete);
|
|
3891 ast->delete_token = token_stream.cursor() - 1;
|
|
3892
|
|
3893 if (token_stream.lookAhead() == '[')
|
|
3894 {
|
|
3895 ast->lbracket_token = token_stream.cursor();
|
|
3896 token_stream.nextToken();
|
|
3897 CHECK(']');
|
|
3898 ast->rbracket_token = token_stream.cursor() - 1;
|
|
3899 }
|
|
3900
|
|
3901 if (!parseCastExpression(ast->expression))
|
|
3902 return false;
|
|
3903
|
|
3904 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3905 node = ast;
|
|
3906
|
|
3907 return true;
|
|
3908 }
|
|
3909
|
|
3910 bool Parser::parseCastExpression(ExpressionAST *&node)
|
|
3911 {
|
|
3912 std::size_t start = token_stream.cursor();
|
|
3913
|
|
3914 if (token_stream.lookAhead() == '(')
|
|
3915 {
|
|
3916 token_stream.nextToken();
|
|
3917
|
|
3918 CastExpressionAST *ast = CreateNode<CastExpressionAST>(_M_pool);
|
|
3919
|
|
3920 if (parseTypeId(ast->type_id))
|
|
3921 {
|
|
3922 if (token_stream.lookAhead() == ')')
|
|
3923 {
|
|
3924 token_stream.nextToken();
|
|
3925
|
|
3926 if (parseCastExpression(ast->expression))
|
|
3927 {
|
|
3928 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3929 node = ast;
|
|
3930
|
|
3931 return true;
|
|
3932 }
|
|
3933 }
|
|
3934 }
|
|
3935 }
|
|
3936
|
|
3937 token_stream.rewind((int) start);
|
|
3938 return parseUnaryExpression(node);
|
|
3939 }
|
|
3940
|
|
3941 bool Parser::parsePmExpression(ExpressionAST *&node)
|
|
3942 {
|
|
3943 std::size_t start = token_stream.cursor();
|
|
3944
|
|
3945 if (!parseCastExpression(node) || !node) // ### fixme
|
|
3946 return false;
|
|
3947
|
|
3948 while (token_stream.lookAhead() == Token_ptrmem)
|
|
3949 {
|
|
3950 std::size_t op = token_stream.cursor();
|
|
3951 token_stream.nextToken();
|
|
3952
|
|
3953 ExpressionAST *rightExpr = 0;
|
|
3954 if (!parseCastExpression(rightExpr))
|
|
3955 return false;
|
|
3956
|
|
3957 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
3958 ast->op = op;
|
|
3959 ast->left_expression = node;
|
|
3960 ast->right_expression = rightExpr;
|
|
3961
|
|
3962 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3963 node = ast;
|
|
3964 }
|
|
3965
|
|
3966 return true;
|
|
3967 }
|
|
3968
|
|
3969 bool Parser::parseMultiplicativeExpression(ExpressionAST *&node)
|
|
3970 {
|
|
3971 std::size_t start = token_stream.cursor();
|
|
3972
|
|
3973 if (!parsePmExpression(node))
|
|
3974 return false;
|
|
3975
|
|
3976 while (token_stream.lookAhead() == '*'
|
|
3977 || token_stream.lookAhead() == '/'
|
|
3978 || token_stream.lookAhead() == '%')
|
|
3979 {
|
|
3980 std::size_t op = token_stream.cursor();
|
|
3981 token_stream.nextToken();
|
|
3982
|
|
3983 ExpressionAST *rightExpr = 0;
|
|
3984 if (!parsePmExpression(rightExpr))
|
|
3985 return false;
|
|
3986
|
|
3987 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
3988 ast->op = op;
|
|
3989 ast->left_expression = node;
|
|
3990 ast->right_expression = rightExpr;
|
|
3991
|
|
3992 UPDATE_POS(ast, start, token_stream.cursor());
|
|
3993 node = ast;
|
|
3994 }
|
|
3995
|
|
3996 return true;
|
|
3997 }
|
|
3998
|
|
3999
|
|
4000 bool Parser::parseAdditiveExpression(ExpressionAST *&node)
|
|
4001 {
|
|
4002 std::size_t start = token_stream.cursor();
|
|
4003
|
|
4004 if (!parseMultiplicativeExpression(node))
|
|
4005 return false;
|
|
4006
|
|
4007 while (token_stream.lookAhead() == '+' || token_stream.lookAhead() == '-')
|
|
4008 {
|
|
4009 std::size_t op = token_stream.cursor();
|
|
4010 token_stream.nextToken();
|
|
4011
|
|
4012 ExpressionAST *rightExpr = 0;
|
|
4013 if (!parseMultiplicativeExpression(rightExpr))
|
|
4014 return false;
|
|
4015
|
|
4016 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4017 ast->op = op;
|
|
4018 ast->left_expression = node;
|
|
4019 ast->right_expression = rightExpr;
|
|
4020
|
|
4021 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4022 node = ast;
|
|
4023 }
|
|
4024
|
|
4025 return true;
|
|
4026 }
|
|
4027
|
|
4028 bool Parser::parseShiftExpression(ExpressionAST *&node)
|
|
4029 {
|
|
4030 std::size_t start = token_stream.cursor();
|
|
4031
|
|
4032 if (!parseAdditiveExpression(node))
|
|
4033 return false;
|
|
4034
|
|
4035 while (token_stream.lookAhead() == Token_shift)
|
|
4036 {
|
|
4037 std::size_t op = token_stream.cursor();
|
|
4038 token_stream.nextToken();
|
|
4039
|
|
4040 ExpressionAST *rightExpr = 0;
|
|
4041 if (!parseAdditiveExpression(rightExpr))
|
|
4042 return false;
|
|
4043
|
|
4044 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4045 ast->op = op;
|
|
4046 ast->left_expression = node;
|
|
4047 ast->right_expression = rightExpr;
|
|
4048
|
|
4049 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4050 node = ast;
|
|
4051 }
|
|
4052
|
|
4053 return true;
|
|
4054 }
|
|
4055
|
|
4056 bool Parser::parseRelationalExpression(ExpressionAST *&node, bool templArgs)
|
|
4057 {
|
|
4058 std::size_t start = token_stream.cursor();
|
|
4059
|
|
4060 if (!parseShiftExpression(node))
|
|
4061 return false;
|
|
4062
|
|
4063 while (token_stream.lookAhead() == '<'
|
|
4064 || (token_stream.lookAhead() == '>' && !templArgs)
|
|
4065 || token_stream.lookAhead() == Token_leq
|
|
4066 || token_stream.lookAhead() == Token_geq)
|
|
4067 {
|
|
4068 std::size_t op = token_stream.cursor();
|
|
4069 token_stream.nextToken();
|
|
4070
|
|
4071 ExpressionAST *rightExpr = 0;
|
|
4072 if (!parseShiftExpression(rightExpr))
|
|
4073 return false;
|
|
4074
|
|
4075 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4076 ast->op = op;
|
|
4077 ast->left_expression = node;
|
|
4078 ast->right_expression = rightExpr;
|
|
4079
|
|
4080 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4081 node = ast;
|
|
4082 }
|
|
4083
|
|
4084 return true;
|
|
4085 }
|
|
4086
|
|
4087 bool Parser::parseEqualityExpression(ExpressionAST *&node, bool templArgs)
|
|
4088 {
|
|
4089 std::size_t start = token_stream.cursor();
|
|
4090
|
|
4091 if (!parseRelationalExpression(node, templArgs))
|
|
4092 return false;
|
|
4093
|
|
4094 while (token_stream.lookAhead() == Token_eq
|
|
4095 || token_stream.lookAhead() == Token_not_eq)
|
|
4096 {
|
|
4097 std::size_t op = token_stream.cursor();
|
|
4098 token_stream.nextToken();
|
|
4099
|
|
4100 ExpressionAST *rightExpr = 0;
|
|
4101 if (!parseRelationalExpression(rightExpr, templArgs))
|
|
4102 return false;
|
|
4103
|
|
4104 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4105 ast->op = op;
|
|
4106 ast->left_expression = node;
|
|
4107 ast->right_expression = rightExpr;
|
|
4108
|
|
4109 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4110 node = ast;
|
|
4111 }
|
|
4112
|
|
4113 return true;
|
|
4114 }
|
|
4115
|
|
4116 bool Parser::parseAndExpression(ExpressionAST *&node, bool templArgs)
|
|
4117 {
|
|
4118 std::size_t start = token_stream.cursor();
|
|
4119
|
|
4120 if (!parseEqualityExpression(node, templArgs))
|
|
4121 return false;
|
|
4122
|
|
4123 while (token_stream.lookAhead() == '&')
|
|
4124 {
|
|
4125 std::size_t op = token_stream.cursor();
|
|
4126 token_stream.nextToken();
|
|
4127
|
|
4128 ExpressionAST *rightExpr = 0;
|
|
4129 if (!parseEqualityExpression(rightExpr, templArgs))
|
|
4130 return false;
|
|
4131
|
|
4132 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4133 ast->op = op;
|
|
4134 ast->left_expression = node;
|
|
4135 ast->right_expression = rightExpr;
|
|
4136
|
|
4137 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4138 node = ast;
|
|
4139 }
|
|
4140
|
|
4141 return true;
|
|
4142 }
|
|
4143
|
|
4144 bool Parser::parseExclusiveOrExpression(ExpressionAST *&node, bool templArgs)
|
|
4145 {
|
|
4146 std::size_t start = token_stream.cursor();
|
|
4147
|
|
4148 if (!parseAndExpression(node, templArgs))
|
|
4149 return false;
|
|
4150
|
|
4151 while (token_stream.lookAhead() == '^')
|
|
4152 {
|
|
4153 std::size_t op = token_stream.cursor();
|
|
4154 token_stream.nextToken();
|
|
4155
|
|
4156 ExpressionAST *rightExpr = 0;
|
|
4157 if (!parseAndExpression(rightExpr, templArgs))
|
|
4158 return false;
|
|
4159
|
|
4160 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4161 ast->op = op;
|
|
4162 ast->left_expression = node;
|
|
4163 ast->right_expression = rightExpr;
|
|
4164
|
|
4165 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4166 node = ast;
|
|
4167 }
|
|
4168
|
|
4169 return true;
|
|
4170 }
|
|
4171
|
|
4172 bool Parser::parseInclusiveOrExpression(ExpressionAST *&node, bool templArgs)
|
|
4173 {
|
|
4174 std::size_t start = token_stream.cursor();
|
|
4175
|
|
4176 if (!parseExclusiveOrExpression(node, templArgs))
|
|
4177 return false;
|
|
4178
|
|
4179 while (token_stream.lookAhead() == '|')
|
|
4180 {
|
|
4181 std::size_t op = token_stream.cursor();
|
|
4182 token_stream.nextToken();
|
|
4183
|
|
4184 ExpressionAST *rightExpr = 0;
|
|
4185 if (!parseExclusiveOrExpression(rightExpr, templArgs))
|
|
4186 return false;
|
|
4187
|
|
4188 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4189 ast->op = op;
|
|
4190 ast->left_expression = node;
|
|
4191 ast->right_expression = rightExpr;
|
|
4192
|
|
4193 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4194 node = ast;
|
|
4195 }
|
|
4196
|
|
4197 return true;
|
|
4198 }
|
|
4199
|
|
4200 bool Parser::parseLogicalAndExpression(ExpressionAST *&node, bool templArgs)
|
|
4201 {
|
|
4202 std::size_t start = token_stream.cursor();
|
|
4203
|
|
4204 if (!parseInclusiveOrExpression(node, templArgs))
|
|
4205 return false;
|
|
4206
|
|
4207 while (token_stream.lookAhead() == Token_and)
|
|
4208 {
|
|
4209 std::size_t op = token_stream.cursor();
|
|
4210 token_stream.nextToken();
|
|
4211
|
|
4212 ExpressionAST *rightExpr = 0;
|
|
4213 if (!parseInclusiveOrExpression(rightExpr, templArgs))
|
|
4214 return false;
|
|
4215
|
|
4216 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4217 ast->op = op;
|
|
4218 ast->left_expression = node;
|
|
4219 ast->right_expression = rightExpr;
|
|
4220
|
|
4221 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4222 node = ast;
|
|
4223 }
|
|
4224
|
|
4225 return true;
|
|
4226 }
|
|
4227
|
|
4228 bool Parser::parseLogicalOrExpression(ExpressionAST *&node, bool templArgs)
|
|
4229 {
|
|
4230 std::size_t start = token_stream.cursor();
|
|
4231
|
|
4232 if (!parseLogicalAndExpression(node, templArgs))
|
|
4233 return false;
|
|
4234
|
|
4235 while (token_stream.lookAhead() == Token_or)
|
|
4236 {
|
|
4237 std::size_t op = token_stream.cursor();
|
|
4238 token_stream.nextToken();
|
|
4239
|
|
4240 ExpressionAST *rightExpr = 0;
|
|
4241 if (!parseLogicalAndExpression(rightExpr, templArgs))
|
|
4242 return false;
|
|
4243
|
|
4244 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4245 ast->op = op;
|
|
4246 ast->left_expression = node;
|
|
4247 ast->right_expression = rightExpr;
|
|
4248
|
|
4249 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4250 node = ast;
|
|
4251 }
|
|
4252
|
|
4253 return true;
|
|
4254 }
|
|
4255
|
|
4256 bool Parser::parseConditionalExpression(ExpressionAST *&node)
|
|
4257 {
|
|
4258 std::size_t start = token_stream.cursor();
|
|
4259
|
|
4260 if (!parseLogicalOrExpression(node))
|
|
4261 return false;
|
|
4262
|
|
4263 if (token_stream.lookAhead() == '?')
|
|
4264 {
|
|
4265 token_stream.nextToken();
|
|
4266
|
|
4267 ExpressionAST *leftExpr = 0;
|
|
4268 if (!parseExpression(leftExpr))
|
|
4269 return false;
|
|
4270
|
|
4271 CHECK(':');
|
|
4272
|
|
4273 ExpressionAST *rightExpr = 0;
|
|
4274 if (!parseAssignmentExpression(rightExpr))
|
|
4275 return false;
|
|
4276
|
|
4277 ConditionalExpressionAST *ast
|
|
4278 = CreateNode<ConditionalExpressionAST>(_M_pool);
|
|
4279
|
|
4280 ast->condition = node;
|
|
4281 ast->left_expression = leftExpr;
|
|
4282 ast->right_expression = rightExpr;
|
|
4283
|
|
4284 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4285 node = ast;
|
|
4286 }
|
|
4287
|
|
4288 return true;
|
|
4289 }
|
|
4290
|
|
4291 bool Parser::parseAssignmentExpression(ExpressionAST *&node)
|
|
4292 {
|
|
4293 std::size_t start = token_stream.cursor();
|
|
4294
|
|
4295 if (token_stream.lookAhead() == Token_throw && !parseThrowExpression(node))
|
|
4296 return false;
|
|
4297 else if (!parseConditionalExpression(node))
|
|
4298 return false;
|
|
4299
|
|
4300 while (token_stream.lookAhead() == Token_assign
|
|
4301 || token_stream.lookAhead() == '=')
|
|
4302 {
|
|
4303 std::size_t op = token_stream.cursor();
|
|
4304 token_stream.nextToken();
|
|
4305
|
|
4306 ExpressionAST *rightExpr = 0;
|
|
4307 if (!parseConditionalExpression(rightExpr))
|
|
4308 return false;
|
|
4309
|
|
4310 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4311 ast->op = op;
|
|
4312 ast->left_expression = node;
|
|
4313 ast->right_expression = rightExpr;
|
|
4314
|
|
4315 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4316 node = ast;
|
|
4317 }
|
|
4318
|
|
4319 return true;
|
|
4320 }
|
|
4321
|
|
4322 bool Parser::parseConstantExpression(ExpressionAST *&node)
|
|
4323 {
|
|
4324 return parseConditionalExpression(node);
|
|
4325 }
|
|
4326
|
|
4327 bool Parser::parseExpression(ExpressionAST *&node)
|
|
4328 {
|
|
4329 return parseCommaExpression(node);
|
|
4330 }
|
|
4331
|
|
4332 bool Parser::parseCommaExpression(ExpressionAST *&node)
|
|
4333 {
|
|
4334 std::size_t start = token_stream.cursor();
|
|
4335
|
|
4336 if (!parseAssignmentExpression(node))
|
|
4337 return false;
|
|
4338
|
|
4339 while (token_stream.lookAhead() == ',')
|
|
4340 {
|
|
4341 std::size_t op = token_stream.cursor();
|
|
4342 token_stream.nextToken();
|
|
4343
|
|
4344 ExpressionAST *rightExpr = 0;
|
|
4345 if (!parseAssignmentExpression(rightExpr))
|
|
4346 return false;
|
|
4347
|
|
4348 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
|
|
4349 ast->op = op;
|
|
4350 ast->left_expression = node;
|
|
4351 ast->right_expression = rightExpr;
|
|
4352
|
|
4353 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4354 node = ast;
|
|
4355 }
|
|
4356
|
|
4357 return true;
|
|
4358 }
|
|
4359
|
|
4360 bool Parser::parseThrowExpression(ExpressionAST *&node)
|
|
4361 {
|
|
4362 std::size_t start = token_stream.cursor();
|
|
4363
|
|
4364 CHECK(Token_throw);
|
|
4365
|
|
4366 ThrowExpressionAST *ast = CreateNode<ThrowExpressionAST>(_M_pool);
|
|
4367 ast->throw_token = token_stream.cursor() - 1;
|
|
4368
|
|
4369 parseAssignmentExpression(ast->expression);
|
|
4370
|
|
4371 UPDATE_POS(ast, start, token_stream.cursor());
|
|
4372 node = ast;
|
|
4373
|
|
4374 return true;
|
|
4375 }
|
|
4376
|
|
4377 bool Parser::parseQ_ENUMS(DeclarationAST *&node)
|
|
4378 {
|
|
4379 if (token_stream.lookAhead() != Token_Q_ENUMS)
|
|
4380 return false;
|
|
4381
|
|
4382 if (token_stream.lookAhead(1) != '(')
|
|
4383 return false;
|
|
4384
|
|
4385 token_stream.nextToken();
|
|
4386 token_stream.nextToken();
|
|
4387
|
|
4388 int firstToken = token_stream.cursor();
|
|
4389 while (token_stream.lookAhead() != ')') {
|
|
4390 token_stream.nextToken();
|
|
4391 }
|
|
4392 QEnumsAST *ast = CreateNode<QEnumsAST>(_M_pool);
|
|
4393 UPDATE_POS(ast, firstToken, token_stream.cursor());
|
|
4394 node = ast;
|
|
4395
|
|
4396 token_stream.nextToken();
|
|
4397
|
|
4398 return true;
|
|
4399 }
|
|
4400
|
|
4401 bool Parser::parseQ_PROPERTY(DeclarationAST *&node)
|
|
4402 {
|
|
4403 if (token_stream.lookAhead() != Token_Q_PROPERTY)
|
|
4404 return false;
|
|
4405
|
|
4406 if (token_stream.lookAhead(1) != '(')
|
|
4407 return false;
|
|
4408
|
|
4409 token_stream.nextToken();
|
|
4410 token_stream.nextToken();
|
|
4411
|
|
4412 int firstToken = token_stream.cursor();
|
|
4413 while (token_stream.lookAhead() != ')') {
|
|
4414 token_stream.nextToken();
|
|
4415 }
|
|
4416 QPropertyAST *ast = CreateNode<QPropertyAST>(_M_pool);
|
|
4417 UPDATE_POS(ast, firstToken, token_stream.cursor());
|
|
4418 node = ast;
|
|
4419
|
|
4420 // const Token &t1 = token_stream[firstToken];
|
|
4421 // const Token &t2 = token_stream[token_stream.cursor()];
|
|
4422 // printf("property: %s\n",
|
|
4423 // qPrintable(QString::fromLatin1(t1.text + t1.position, t2.position - t1.position)));
|
|
4424
|
|
4425 token_stream.nextToken();
|
|
4426
|
|
4427 return true;
|
|
4428 }
|
|
4429
|
|
4430 bool Parser::block_errors(bool block)
|
|
4431 {
|
|
4432 bool current = _M_block_errors;
|
|
4433 _M_block_errors = block;
|
|
4434 return current;
|
|
4435 }
|
|
4436
|
|
4437
|
|
4438 // kate: space-indent on; indent-width 2; replace-tabs on;
|