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;