Mercurial > projects > qtd
comparison generator/parser/parser.cpp @ 1:e78566595089
initial import
author | mandel |
---|---|
date | Mon, 11 May 2009 16:01:50 +0000 |
parents | |
children | 09a0f1d048f2 |
comparison
equal
deleted
inserted
replaced
0:36fb74dc547d | 1:e78566595089 |
---|---|
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; |