source: trunk/tools/porting/src/parser.cpp@ 315

Last change on this file since 315 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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