support for creating template instance classes
[lqt/mk.git] / cpptoxml / parser / parser.cpp
blob5f9e227eb7ec6396c1759a687e500cff66fd389d
1 /****************************************************************************
2 **
3 ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
4 ** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
5 **
6 ** This file is part of the Qt Script Generator project on Trolltech Labs.
7 **
8 ** This file may be used under the terms of the GNU General Public
9 ** License version 2.0 as published by the Free Software Foundation
10 ** and appearing in the file LICENSE.GPL included in the packaging of
11 ** this file. Please review the following information to ensure GNU
12 ** General Public Licensing requirements will be met:
13 ** http://www.trolltech.com/products/qt/opensource.html
15 ** If you are unsure which license is appropriate for your use, please
16 ** review the following information:
17 ** http://www.trolltech.com/products/qt/licensing.html or contact the
18 ** sales department at sales@trolltech.com.
20 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
21 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 ****************************************************************************/
25 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
28 // c++ support
29 #include "parser.h"
30 #include "tokens.h"
31 #include "lexer.h"
32 #include "control.h"
34 #include <cstdlib>
35 #include <iostream>
37 #define ADVANCE(tk, descr) \
38 { \
39 if (token_stream.lookAhead() != tk) { \
40 tokenRequiredError(tk); \
41 return false; \
42 } \
43 token_stream.nextToken(); \
46 #define ADVANCE_NR(tk, descr) \
47 do { \
48 if (token_stream.lookAhead() != tk) { \
49 tokenRequiredError(tk); \
50 } \
51 else \
52 token_stream.nextToken(); \
53 } while (0)
55 #define CHECK(tk) \
56 do { \
57 if (token_stream.lookAhead() != tk) { \
58 return false; \
59 } \
60 token_stream.nextToken(); \
61 } while (0)
63 #define UPDATE_POS(_node, start, end) \
64 do { \
65 (_node)->start_token = start; \
66 (_node)->end_token = end; \
67 } while (0)
69 Parser::Parser(Control *c)
70 : _M_location(token_stream, location_table, line_table),
71 control(c),
72 lexer(_M_location, control)
74 _M_block_errors = false;
77 Parser::~Parser()
81 void Parser::advance()
83 token_stream.nextToken();
86 TranslationUnitAST *Parser::parse(const char *contents,
87 std::size_t size, pool *p)
89 _M_block_errors = false;
90 _M_pool = p;
91 lexer.tokenize(contents, size);
92 token_stream.nextToken(); // skip the first token
94 Lexer *oldLexer = control->changeLexer (&lexer);
95 Parser *oldParser = control->changeParser (this);
97 TranslationUnitAST *ast = 0;
98 parseTranslationUnit(ast);
100 control->changeLexer (oldLexer);
101 control->changeParser (oldParser);
103 return ast;
106 bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node)
108 if (token_stream.lookAhead() != Token_identifier)
109 return false;
111 std::size_t start = token_stream.cursor();
113 const NameSymbol *name_symbol = token_stream.symbol(token_stream.cursor());
114 QString name = name_symbol->as_string();
115 if (name != QLatin1String("__declspec"))
116 return false;
117 std::size_t specifier = token_stream.cursor();
119 token_stream.nextToken();
120 if (token_stream.lookAhead() != '(')
121 return false;
123 token_stream.nextToken();
124 if (token_stream.lookAhead() != Token_identifier)
125 return false;
126 std::size_t modifier = token_stream.cursor();
128 token_stream.nextToken();
129 if (token_stream.lookAhead() != ')')
130 return false;
132 token_stream.nextToken();
134 node = CreateNode<WinDeclSpecAST>(_M_pool);
135 node->specifier = specifier;
136 node->modifier = modifier;
138 UPDATE_POS(node, start, token_stream.cursor());
140 return true;
143 void Parser::tokenRequiredError(int token)
145 QString err;
147 err += "expected token ";
148 err += "``";
149 err += token_name(token);
150 err += "'' found ``";
151 err += token_name(token_stream.lookAhead());
152 err += "''";
154 reportError(err);
157 void Parser::syntaxError()
159 QString err;
161 err += "unexpected token ";
162 err += "``";
163 err += token_name(token_stream.lookAhead());
164 err += "''";
166 reportError(err);
169 void Parser::reportError(const QString& msg)
171 if (!_M_block_errors)
173 int line, column;
174 QString fileName;
176 std::size_t tok = token_stream.cursor();
177 location().positionAt(token_stream.position(tok),
178 &line, &column, &fileName);
180 Control::ErrorMessage errmsg;
181 errmsg.setLine(line + 1);
182 errmsg.setColumn(column);
183 errmsg.setFileName(fileName);
184 errmsg.setMessage(QLatin1String("** PARSER ERROR ") + msg);
185 control->reportError(errmsg);
189 bool Parser::skipUntil(int token)
191 while (token_stream.lookAhead())
193 if (token_stream.lookAhead() == token)
194 return true;
196 token_stream.nextToken();
199 return false;
202 bool Parser::skipUntilDeclaration()
204 while (token_stream.lookAhead())
207 switch(token_stream.lookAhead())
209 case ';':
210 case '~':
211 case Token_scope:
212 case Token_identifier:
213 case Token_operator:
214 case Token_char:
215 case Token_wchar_t:
216 case Token_bool:
217 case Token_short:
218 case Token_int:
219 case Token_long:
220 case Token_signed:
221 case Token_unsigned:
222 case Token_float:
223 case Token_double:
224 case Token_void:
225 case Token_extern:
226 case Token_namespace:
227 case Token_using:
228 case Token_typedef:
229 case Token_asm:
230 case Token_template:
231 case Token_export:
233 case Token_const: // cv
234 case Token_volatile: // cv
236 case Token_public:
237 case Token_protected:
238 case Token_private:
239 case Token_signals: // Qt
240 case Token_slots: // Qt
241 return true;
243 default:
244 token_stream.nextToken();
248 return false;
251 bool Parser::skipUntilStatement()
253 while (token_stream.lookAhead())
255 switch(token_stream.lookAhead())
257 case ';':
258 case '{':
259 case '}':
260 case Token_const:
261 case Token_volatile:
262 case Token_identifier:
263 case Token_case:
264 case Token_default:
265 case Token_if:
266 case Token_switch:
267 case Token_while:
268 case Token_do:
269 case Token_for:
270 case Token_break:
271 case Token_continue:
272 case Token_return:
273 case Token_goto:
274 case Token_try:
275 case Token_catch:
276 case Token_throw:
277 case Token_char:
278 case Token_wchar_t:
279 case Token_bool:
280 case Token_short:
281 case Token_int:
282 case Token_long:
283 case Token_signed:
284 case Token_unsigned:
285 case Token_float:
286 case Token_double:
287 case Token_void:
288 case Token_class:
289 case Token_struct:
290 case Token_union:
291 case Token_enum:
292 case Token_scope:
293 case Token_template:
294 case Token_using:
295 return true;
297 default:
298 token_stream.nextToken();
302 return false;
305 bool Parser::skip(int l, int r)
307 int count = 0;
308 while (token_stream.lookAhead())
310 int tk = token_stream.lookAhead();
312 if (tk == l)
313 ++count;
314 else if (tk == r)
315 --count;
316 else if (l != '{' && (tk == '{' || tk == '}' || tk == ';'))
317 return false;
319 if (count == 0)
320 return true;
322 token_stream.nextToken();
325 return false;
328 bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
330 std::size_t start = token_stream.cursor();
332 WinDeclSpecAST *winDeclSpec = 0;
333 parseWinDeclSpec(winDeclSpec);
335 NameAST *ast = CreateNode<NameAST>(_M_pool);
337 if (token_stream.lookAhead() == Token_scope)
339 ast->global = true;
340 token_stream.nextToken();
343 std::size_t idx = token_stream.cursor();
345 while (true)
347 UnqualifiedNameAST *n = 0;
348 if (!parseUnqualifiedName(n))
349 return false;
351 if (token_stream.lookAhead() == Token_scope)
353 token_stream.nextToken();
355 ast->qualified_names
356 = snoc(ast->qualified_names, n, _M_pool);
358 if (token_stream.lookAhead() == Token_template)
360 /// skip optional template #### @todo CHECK
361 token_stream.nextToken();
364 else
366 Q_ASSERT(n != 0);
367 if (!acceptTemplateId)
369 token_stream.rewind((int) n->start_token);
370 parseUnqualifiedName(n, false);
373 ast->unqualified_name = n;
374 break;
378 if (idx == token_stream.cursor())
379 return false;
381 UPDATE_POS(ast, start, token_stream.cursor());
382 node = ast;
384 return true;
387 bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
389 std::size_t start = token_stream.cursor();
390 TranslationUnitAST *ast = CreateNode<TranslationUnitAST>(_M_pool);
392 while (token_stream.lookAhead())
394 std::size_t startDecl = token_stream.cursor();
396 DeclarationAST *declaration = 0;
397 if (parseDeclaration(declaration))
399 ast->declarations =
400 snoc(ast->declarations, declaration, _M_pool);
402 else
404 // error recovery
405 if (startDecl == token_stream.cursor())
407 // skip at least one token
408 token_stream.nextToken();
411 skipUntilDeclaration();
415 UPDATE_POS(ast, start, token_stream.cursor());
416 node = ast;
418 return true;
421 bool Parser::parseDeclaration(DeclarationAST *&node)
423 std::size_t start = token_stream.cursor();
425 switch(token_stream.lookAhead())
427 case ';':
428 token_stream.nextToken();
429 return true;
431 case Token_extern:
432 return parseLinkageSpecification(node);
434 case Token_namespace:
435 return parseNamespace(node);
437 case Token_using:
438 return parseUsing(node);
440 case Token_typedef:
441 return parseTypedef(node);
443 case Token_asm:
444 return parseAsmDefinition(node);
446 case Token_Q_ENUMS:
447 return parseQ_ENUMS(node);
449 case Token_template:
450 case Token_export:
451 return parseTemplateDeclaration(node);
453 default:
455 const ListNode<std::size_t> *cv = 0;
456 parseCvQualify(cv);
458 const ListNode<std::size_t> *storageSpec = 0;
459 parseStorageClassSpecifier(storageSpec);
461 parseCvQualify(cv);
463 TypeSpecifierAST *spec = 0;
464 if (parseEnumSpecifier(spec)
465 || parseClassSpecifier(spec)
466 || parseForwardDeclarationSpecifier(spec))
468 parseCvQualify(cv);
470 spec->cv = cv;
472 const ListNode<InitDeclaratorAST*> *declarators = 0;
473 parseInitDeclaratorList(declarators);
474 ADVANCE(';', ";");
476 SimpleDeclarationAST *ast =
477 CreateNode<SimpleDeclarationAST>(_M_pool);
479 ast->storage_specifiers = storageSpec;
480 ast->type_specifier = spec;
481 ast->init_declarators = declarators;
482 UPDATE_POS(ast, start, token_stream.cursor());
483 node = ast;
485 return true;
488 } // end switch
490 token_stream.rewind((int) start);
491 return parseDeclarationInternal(node);
494 bool Parser::parseLinkageSpecification(DeclarationAST *&node)
496 std::size_t start = token_stream.cursor();
498 CHECK(Token_extern);
500 LinkageSpecificationAST *ast = CreateNode<LinkageSpecificationAST>(_M_pool);
502 if (token_stream.lookAhead() == Token_string_literal)
504 ast->extern_type = token_stream.cursor();
505 token_stream.nextToken();
508 if (token_stream.lookAhead() == '{')
510 parseLinkageBody(ast->linkage_body);
512 else if (!parseDeclaration(ast->declaration))
514 reportError(("Declaration syntax error"));
517 UPDATE_POS(ast, start, token_stream.cursor());
518 node = ast;
520 return true;
523 bool Parser::parseLinkageBody(LinkageBodyAST *&node)
525 std::size_t start = token_stream.cursor();
527 CHECK('{');
529 LinkageBodyAST *ast = CreateNode<LinkageBodyAST>(_M_pool);
531 while (token_stream.lookAhead())
533 int tk = token_stream.lookAhead();
535 if (tk == '}')
536 break;
538 std::size_t startDecl = token_stream.cursor();
540 DeclarationAST *declaration = 0;
541 if (parseDeclaration(declaration))
543 ast->declarations = snoc(ast->declarations, declaration, _M_pool);
545 else
547 // error recovery
548 if (startDecl == token_stream.cursor())
550 // skip at least one token
551 token_stream.nextToken();
554 skipUntilDeclaration();
558 if (token_stream.lookAhead() != '}')
559 reportError(("} expected"));
560 else
561 token_stream.nextToken();
563 UPDATE_POS(ast, start, token_stream.cursor());
564 node = ast;
566 return true;
569 bool Parser::parseNamespace(DeclarationAST *&node)
571 std::size_t start = token_stream.cursor();
573 CHECK(Token_namespace);
575 std::size_t namespace_name = 0;
576 if (token_stream.lookAhead() == Token_identifier)
578 namespace_name = token_stream.cursor();
579 token_stream.nextToken();
582 if (token_stream.lookAhead() == '=')
584 // namespace alias
585 token_stream.nextToken();
587 NameAST *name = 0;
588 if (parseName(name))
590 ADVANCE(';', ";");
592 NamespaceAliasDefinitionAST *ast
593 = CreateNode<NamespaceAliasDefinitionAST>(_M_pool);
594 ast->namespace_name = namespace_name;
595 ast->alias_name = name;
596 UPDATE_POS(ast, start, token_stream.cursor());
597 node = ast;
598 return true;
600 else
602 reportError(("namespace expected"));
603 return false;
606 else if (token_stream.lookAhead() != '{')
608 reportError(("{ expected"));
609 return false;
612 NamespaceAST *ast = CreateNode<NamespaceAST>(_M_pool);
613 ast->namespace_name = namespace_name;
614 parseLinkageBody(ast->linkage_body);
616 UPDATE_POS(ast, start, token_stream.cursor());
617 node = ast;
619 return true;
622 bool Parser::parseUsing(DeclarationAST *&node)
624 std::size_t start = token_stream.cursor();
626 CHECK(Token_using);
628 if (token_stream.lookAhead() == Token_namespace)
629 return parseUsingDirective(node);
631 UsingAST *ast = CreateNode<UsingAST>(_M_pool);
633 if (token_stream.lookAhead() == Token_typename)
635 ast->type_name = token_stream.cursor();
636 token_stream.nextToken();
639 if (!parseName(ast->name))
640 return false;
642 ADVANCE(';', ";");
644 UPDATE_POS(ast, start, token_stream.cursor());
645 node = ast;
647 return true;
650 bool Parser::parseUsingDirective(DeclarationAST *&node)
652 std::size_t start = token_stream.cursor();
654 CHECK(Token_namespace);
656 NameAST *name = 0;
657 if (!parseName(name))
659 reportError(("Namespace name expected"));
660 return false;
663 ADVANCE(';', ";");
665 UsingDirectiveAST *ast = CreateNode<UsingDirectiveAST>(_M_pool);
666 ast->name = name;
667 UPDATE_POS(ast, start, token_stream.cursor());
668 node = ast;
670 return true;
674 bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node)
676 std::size_t start = token_stream.cursor();
678 CHECK(Token_operator);
680 OperatorFunctionIdAST *ast = CreateNode<OperatorFunctionIdAST>(_M_pool);
682 if (!parseOperator(ast->op))
684 ast->op = 0;
686 // parse cast operator
687 const ListNode<std::size_t> *cv = 0;
688 parseCvQualify(cv);
690 if (!parseSimpleTypeSpecifier(ast->type_specifier))
692 syntaxError();
693 return false;
696 parseCvQualify(cv);
697 ast->type_specifier->cv = cv;
699 PtrOperatorAST *ptr_op = 0;
700 while (parsePtrOperator(ptr_op))
701 ast->ptr_ops = snoc(ast->ptr_ops, ptr_op, _M_pool);
704 UPDATE_POS(ast, start, token_stream.cursor());
705 node = ast;
706 return true;
709 bool Parser::parseTemplateArgumentList(const ListNode<TemplateArgumentAST*> *&node,
710 bool reportError)
712 TemplateArgumentAST *templArg = 0;
713 if (!parseTemplateArgument(templArg))
714 return false;
716 node = snoc(node, templArg, _M_pool);
718 while (token_stream.lookAhead() == ',')
720 token_stream.nextToken();
722 if (!parseTemplateArgument(templArg))
724 if (reportError)
726 syntaxError();
727 break;
730 node = 0;
731 return false;
734 node = snoc(node, templArg, _M_pool);
737 return true;
740 bool Parser::parseTypedef(DeclarationAST *&node)
742 std::size_t start = token_stream.cursor();
744 CHECK(Token_typedef);
746 TypeSpecifierAST *spec = 0;
747 if (!parseTypeSpecifierOrClassSpec(spec))
749 reportError(("Need a type specifier to declare"));
750 return false;
753 const ListNode<InitDeclaratorAST*> *declarators = 0;
754 if (!parseInitDeclaratorList(declarators))
756 //reportError(("Need an identifier to declare"));
757 //return false;
760 ADVANCE(';', ";");
762 TypedefAST *ast = CreateNode<TypedefAST>(_M_pool);
763 ast->type_specifier = spec;
764 ast->init_declarators = declarators;
766 UPDATE_POS(ast, start, token_stream.cursor());
767 node = ast;
769 return true;
772 bool Parser::parseAsmDefinition(DeclarationAST *&node)
774 std::size_t start = token_stream.cursor();
776 ADVANCE(Token_asm, "asm");
778 const ListNode<std::size_t> *cv = 0;
779 parseCvQualify(cv);
781 #if defined(__GNUC__)
782 #warning "implement me"
783 #endif
784 skip('(', ')');
785 token_stream.nextToken();
786 ADVANCE(';', ";");
788 AsmDefinitionAST *ast = CreateNode<AsmDefinitionAST>(_M_pool);
789 ast->cv = cv;
790 UPDATE_POS(ast, start, token_stream.cursor());
791 node = ast;
793 return true;
796 bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
798 std::size_t start = token_stream.cursor();
800 std::size_t exported = 0;
801 if (token_stream.lookAhead() == Token_export)
803 exported = token_stream.cursor();
804 token_stream.nextToken();
807 CHECK(Token_template);
809 const ListNode<TemplateParameterAST*> *params = 0;
810 if (token_stream.lookAhead() == '<')
812 token_stream.nextToken();
813 parseTemplateParameterList(params);
815 ADVANCE('>', ">");
818 DeclarationAST *declaration = 0;
819 if (!parseDeclaration(declaration))
821 reportError(("expected a declaration"));
824 TemplateDeclarationAST *ast = CreateNode<TemplateDeclarationAST>(_M_pool);
825 ast->exported = exported;
826 ast->template_parameters = params;
827 ast->declaration = declaration;
829 UPDATE_POS(ast, start, token_stream.cursor());
830 node = ast;
832 return true;
835 bool Parser::parseOperator(OperatorAST *&node)
837 std::size_t start = token_stream.cursor();
839 OperatorAST *ast = CreateNode<OperatorAST>(_M_pool);
841 switch(token_stream.lookAhead())
843 case Token_new:
844 case Token_delete:
846 ast->op = token_stream.cursor();
847 token_stream.nextToken();
849 if (token_stream.lookAhead() == '['
850 && token_stream.lookAhead(1) == ']')
852 ast->open = token_stream.cursor();
853 token_stream.nextToken();
855 ast->close = token_stream.cursor();
856 token_stream.nextToken();
859 break;
861 case '+':
862 case '-':
863 case '*':
864 case '/':
865 case '%':
866 case '^':
867 case '&':
868 case '|':
869 case '~':
870 case '!':
871 case '=':
872 case '<':
873 case '>':
874 case ',':
875 case Token_assign:
876 case Token_shift:
877 case Token_eq:
878 case Token_not_eq:
879 case Token_leq:
880 case Token_geq:
881 case Token_and:
882 case Token_or:
883 case Token_incr:
884 case Token_decr:
885 case Token_ptrmem:
886 case Token_arrow:
887 ast->op = token_stream.cursor();
888 token_stream.nextToken();
889 break;
891 default:
892 if (token_stream.lookAhead() == '('
893 && token_stream.lookAhead(1) == ')')
895 ast->op = ast->open = token_stream.cursor();
896 token_stream.nextToken();
897 ast->close = token_stream.cursor();
898 token_stream.nextToken();
900 else if (token_stream.lookAhead() == '['
901 && token_stream.lookAhead(1) == ']')
903 ast->op = ast->open = token_stream.cursor();
904 token_stream.nextToken();
905 ast->close = token_stream.cursor();
906 token_stream.nextToken();
908 else
910 return false;
914 UPDATE_POS(ast, start, token_stream.cursor());
915 node = ast;
917 return true;
920 bool Parser::parseCvQualify(const ListNode<std::size_t> *&node)
922 std::size_t start = token_stream.cursor();
924 int tk;
925 while (0 != (tk = token_stream.lookAhead())
926 && (tk == Token_const || tk == Token_volatile))
928 node = snoc(node, token_stream.cursor(), _M_pool);
929 token_stream.nextToken();
932 return start != token_stream.cursor();
935 bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node,
936 bool onlyIntegral)
938 std::size_t start = token_stream.cursor();
939 bool isIntegral = false;
940 bool done = false;
942 const ListNode<std::size_t> *integrals = 0;
944 while (!done)
946 switch(token_stream.lookAhead())
948 case Token_char:
949 case Token_wchar_t:
950 case Token_bool:
951 case Token_short:
952 case Token_int:
953 case Token_long:
954 case Token_signed:
955 case Token_unsigned:
956 case Token_float:
957 case Token_double:
958 case Token_void:
959 integrals = snoc(integrals, token_stream.cursor(), _M_pool);
960 isIntegral = true;
961 token_stream.nextToken();
962 break;
964 default:
965 done = true;
969 SimpleTypeSpecifierAST *ast = CreateNode<SimpleTypeSpecifierAST>(_M_pool);
970 if (isIntegral)
972 ast->integrals = integrals;
974 else if (token_stream.lookAhead() == Token___typeof)
976 ast->type_of = token_stream.cursor();
977 token_stream.nextToken();
979 if (token_stream.lookAhead() == '(')
981 token_stream.nextToken();
983 std::size_t saved = token_stream.cursor();
984 parseTypeId(ast->type_id);
985 if (token_stream.lookAhead() != ')')
987 ast->type_id = 0;
988 token_stream.rewind((int) saved);
989 parseUnaryExpression(ast->expression);
991 ADVANCE(')', ")");
993 else
995 parseUnaryExpression(ast->expression);
998 else if (onlyIntegral)
1000 token_stream.rewind((int) start);
1001 return false;
1003 else
1005 if (!parseName(ast->name, true))
1007 ast->name = 0;
1008 token_stream.rewind((int) start);
1009 return false;
1013 UPDATE_POS(ast, start, token_stream.cursor());
1014 node = ast;
1016 return true;
1019 bool Parser::parsePtrOperator(PtrOperatorAST *&node)
1021 int tk = token_stream.lookAhead();
1023 if (tk != '&' && tk != '*'
1024 && tk != Token_scope && tk != Token_identifier)
1026 return false;
1029 std::size_t start = token_stream.cursor();
1031 PtrOperatorAST *ast = CreateNode<PtrOperatorAST>(_M_pool);
1033 switch (token_stream.lookAhead())
1035 case '&':
1036 case '*':
1037 ast->op = token_stream.cursor();
1038 token_stream.nextToken();
1039 break;
1041 case Token_scope:
1042 case Token_identifier:
1044 if (!parsePtrToMember(ast->mem_ptr))
1046 token_stream.rewind((int) start);
1047 return false;
1050 break;
1052 default:
1053 Q_ASSERT(0);
1054 break;
1057 parseCvQualify(ast->cv);
1059 UPDATE_POS(ast, start, token_stream.cursor());
1060 node = ast;
1062 return true;
1065 bool Parser::parseTemplateArgument(TemplateArgumentAST *&node)
1067 std::size_t start = token_stream.cursor();
1069 TypeIdAST *typeId = 0;
1070 ExpressionAST *expr = 0;
1072 if (!parseTypeId(typeId) || (token_stream.lookAhead() != ','
1073 && token_stream.lookAhead() != '>'))
1075 token_stream.rewind((int) start);
1077 if (!parseLogicalOrExpression(expr, true))
1078 return false;
1081 TemplateArgumentAST *ast = CreateNode<TemplateArgumentAST>(_M_pool);
1082 ast->type_id = typeId;
1083 ast->expression = expr;
1085 UPDATE_POS(ast, start, token_stream.cursor());
1086 node = ast;
1088 return true;
1091 bool Parser::parseTypeSpecifier(TypeSpecifierAST *&node)
1093 std::size_t start = token_stream.cursor();
1095 const ListNode<std::size_t> *cv = 0;
1096 parseCvQualify(cv);
1098 TypeSpecifierAST *ast = 0;
1099 if (!parseElaboratedTypeSpecifier(ast) && !parseSimpleTypeSpecifier(ast))
1101 token_stream.rewind((int) start);
1102 return false;
1105 parseCvQualify(cv);
1106 ast->cv = cv;
1108 node = ast;
1110 return true;
1113 bool Parser::parseDeclarator(DeclaratorAST *&node)
1115 std::size_t start = token_stream.cursor();
1117 DeclaratorAST *ast = CreateNode<DeclaratorAST>(_M_pool);
1119 DeclaratorAST *decl = 0;
1120 NameAST *declId = 0;
1122 PtrOperatorAST *ptrOp = 0;
1123 while (parsePtrOperator(ptrOp))
1125 ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool);
1128 if (token_stream.lookAhead() == '(')
1130 token_stream.nextToken();
1132 if (!parseDeclarator(decl))
1133 return false;
1135 ast->sub_declarator = decl;
1137 CHECK(')');
1139 else
1141 if (token_stream.lookAhead() == ':')
1143 // unnamed bitfield
1145 else if (parseName(declId, true))
1147 ast->id = declId;
1149 else
1151 token_stream.rewind((int) start);
1152 return false;
1155 if (token_stream.lookAhead() == ':')
1157 token_stream.nextToken();
1159 if (!parseConstantExpression(ast->bit_expression))
1161 reportError(("Constant expression expected"));
1163 goto update_pos;
1168 bool isVector = true;
1170 while (token_stream.lookAhead() == '[')
1172 token_stream.nextToken();
1174 ExpressionAST *expr = 0;
1175 parseCommaExpression(expr);
1177 ADVANCE(']', "]");
1179 ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool);
1180 isVector = true;
1183 bool skipParen = false;
1184 if (token_stream.lookAhead() == Token_identifier
1185 && token_stream.lookAhead(1) == '('
1186 && token_stream.lookAhead(2) == '(')
1188 token_stream.nextToken();
1189 token_stream.nextToken();
1190 skipParen = true;
1193 int tok = token_stream.lookAhead();
1194 if (ast->sub_declarator
1195 && !(isVector || tok == '(' || tok == ','
1196 || tok == ';' || tok == '='))
1198 token_stream.rewind((int) start);
1199 return false;
1202 std::size_t index = token_stream.cursor();
1203 if (token_stream.lookAhead() == '(')
1205 token_stream.nextToken();
1207 ParameterDeclarationClauseAST *params = 0;
1208 if (!parseParameterDeclarationClause(params))
1210 token_stream.rewind((int) index);
1211 goto update_pos;
1214 ast->parameter_declaration_clause = params;
1216 if (token_stream.lookAhead() != ')')
1218 token_stream.rewind((int) index);
1219 goto update_pos;
1222 token_stream.nextToken(); // skip ')'
1224 parseCvQualify(ast->fun_cv);
1225 parseExceptionSpecification(ast->exception_spec);
1227 if (token_stream.lookAhead() == Token___attribute__)
1229 parse_Attribute__();
1233 if (skipParen)
1235 if (token_stream.lookAhead() != ')')
1237 reportError(("')' expected"));
1239 else
1240 token_stream.nextToken();
1244 update_pos:
1245 UPDATE_POS(ast, start, token_stream.cursor());
1246 node = ast;
1248 return true;
1251 bool Parser::parseAbstractDeclarator(DeclaratorAST *&node)
1253 std::size_t start = token_stream.cursor();
1255 DeclaratorAST *ast = CreateNode<DeclaratorAST>(_M_pool);
1256 DeclaratorAST *decl = 0;
1258 PtrOperatorAST *ptrOp = 0;
1259 while (parsePtrOperator(ptrOp))
1261 ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool);
1264 int index = (int) token_stream.cursor();
1265 if (token_stream.lookAhead() == '(')
1267 token_stream.nextToken();
1269 if (!parseAbstractDeclarator(decl))
1271 token_stream.rewind((int) index);
1272 goto label1;
1275 ast->sub_declarator = decl;
1277 if (token_stream.lookAhead() != ')')
1279 token_stream.rewind((int) start);
1280 return false;
1282 token_stream.nextToken();
1284 else if (token_stream.lookAhead() == ':')
1286 token_stream.nextToken();
1287 if (!parseConstantExpression(ast->bit_expression))
1289 ast->bit_expression = 0;
1290 reportError(("Constant expression expected"));
1292 goto update_pos;
1295 label1:
1297 bool isVector = true;
1299 while (token_stream.lookAhead() == '[')
1301 token_stream.nextToken();
1303 ExpressionAST *expr = 0;
1304 parseCommaExpression(expr);
1306 ADVANCE(']', "]");
1308 ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool);
1309 isVector = true;
1312 int tok = token_stream.lookAhead();
1313 if (ast->sub_declarator
1314 && !(isVector || tok == '(' || tok == ','
1315 || tok == ';' || tok == '='))
1317 token_stream.rewind((int) start);
1318 return false;
1321 int index = (int) token_stream.cursor();
1322 if (token_stream.lookAhead() == '(')
1324 token_stream.nextToken();
1326 ParameterDeclarationClauseAST *params = 0;
1327 if (!parseParameterDeclarationClause(params))
1329 token_stream.rewind((int) index);
1330 goto update_pos;
1333 ast->parameter_declaration_clause = params;
1335 if (token_stream.lookAhead() != ')')
1337 token_stream.rewind((int) index);
1338 goto update_pos;
1341 token_stream.nextToken(); // skip ')'
1343 parseCvQualify(ast->fun_cv);
1344 parseExceptionSpecification(ast->exception_spec);
1348 update_pos:
1349 if (token_stream.cursor() == start)
1350 return false;
1352 UPDATE_POS(ast, start, token_stream.cursor());
1353 node = ast;
1355 return true;
1358 bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node)
1360 std::size_t start = token_stream.cursor();
1362 CHECK(Token_enum);
1364 NameAST *name = 0;
1365 parseName(name);
1367 if (token_stream.lookAhead() != '{')
1369 token_stream.rewind((int) start);
1370 return false;
1372 token_stream.nextToken();
1374 EnumSpecifierAST *ast = CreateNode<EnumSpecifierAST>(_M_pool);
1375 ast->name = name;
1377 EnumeratorAST *enumerator = 0;
1378 if (parseEnumerator(enumerator))
1380 ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool);
1382 while (token_stream.lookAhead() == ',')
1384 token_stream.nextToken();
1386 if (!parseEnumerator(enumerator))
1388 //reportError(("Enumerator expected"));
1389 break;
1392 ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool);
1396 ADVANCE_NR('}', "}");
1398 UPDATE_POS(ast, start, token_stream.cursor());
1399 node = ast;
1401 return true;
1404 bool Parser::parseTemplateParameterList(const ListNode<TemplateParameterAST*> *&node)
1406 TemplateParameterAST *param = 0;
1407 if (!parseTemplateParameter(param))
1408 return false;
1410 node = snoc(node, param, _M_pool);
1412 while (token_stream.lookAhead() == ',')
1414 token_stream.nextToken();
1416 if (!parseTemplateParameter(param))
1418 syntaxError();
1419 break;
1421 else
1423 node = snoc(node, param, _M_pool);
1427 return true;
1430 bool Parser::parseTemplateParameter(TemplateParameterAST *&node)
1432 std::size_t start = token_stream.cursor();
1433 TemplateParameterAST *ast = CreateNode<TemplateParameterAST>(_M_pool);
1435 int tk = token_stream.lookAhead();
1437 if ((tk == Token_class || tk == Token_typename || tk == Token_template)
1438 && parseTypeParameter(ast->type_parameter))
1440 // nothing to do
1442 else if (!parseParameterDeclaration(ast->parameter_declaration))
1443 return false;
1445 UPDATE_POS(ast, start, token_stream.cursor());
1446 node = ast;
1448 return true;
1451 bool Parser::parseTypeParameter(TypeParameterAST *&node)
1453 std::size_t start = token_stream.cursor();
1455 TypeParameterAST *ast = CreateNode<TypeParameterAST>(_M_pool);
1456 ast->type = start;
1458 switch(token_stream.lookAhead())
1460 case Token_class:
1461 case Token_typename:
1463 token_stream.nextToken(); // skip class
1465 // parse optional name
1466 if(parseName(ast->name, true))
1468 if (token_stream.lookAhead() == '=')
1470 token_stream.nextToken();
1472 if(!parseTypeId(ast->type_id))
1474 //syntaxError();
1475 token_stream.rewind((int) start);
1476 return false;
1479 else if (token_stream.lookAhead() != ','
1480 && token_stream.lookAhead() != '>')
1482 token_stream.rewind((int) start);
1483 return false;
1487 break;
1489 case Token_template:
1491 token_stream.nextToken(); // skip template
1492 ADVANCE('<', "<");
1494 if (!parseTemplateParameterList(ast->template_parameters))
1495 return false;
1497 ADVANCE('>', ">");
1499 if (token_stream.lookAhead() == Token_class)
1500 token_stream.nextToken();
1502 // parse optional name
1503 if (parseName(ast->name, true))
1505 if (token_stream.lookAhead() == '=')
1507 token_stream.nextToken();
1509 if (!parseTypeId(ast->type_id))
1511 syntaxError();
1512 return false;
1517 if (token_stream.lookAhead() == '=')
1519 token_stream.nextToken();
1521 parseName(ast->template_name, true);
1524 break;
1526 default:
1527 return false;
1529 } // end switch
1532 UPDATE_POS(ast, start, token_stream.cursor());
1533 node = ast;
1534 return true;
1537 bool Parser::parseStorageClassSpecifier(const ListNode<std::size_t> *&node)
1539 std::size_t start = token_stream.cursor();
1541 int tk;
1542 while (0 != (tk = token_stream.lookAhead())
1543 && (tk == Token_friend || tk == Token_auto
1544 || tk == Token_register || tk == Token_static
1545 || tk == Token_extern || tk == Token_mutable))
1547 node = snoc(node, token_stream.cursor(), _M_pool);
1548 token_stream.nextToken();
1551 return start != token_stream.cursor();
1554 bool Parser::parseFunctionSpecifier(const ListNode<std::size_t> *&node)
1556 std::size_t start = token_stream.cursor();
1558 int tk;
1559 while (0 != (tk = token_stream.lookAhead())
1560 && (tk == Token_inline || tk == Token_virtual
1561 || tk == Token_explicit || tk == Token_Q_INVOKABLE))
1563 node = snoc(node, token_stream.cursor(), _M_pool);
1564 token_stream.nextToken();
1567 return start != token_stream.cursor();
1570 bool Parser::parseTypeId(TypeIdAST *&node)
1572 /// @todo implement the AST for typeId
1573 std::size_t start = token_stream.cursor();
1575 TypeSpecifierAST *spec = 0;
1576 if (!parseTypeSpecifier(spec))
1578 token_stream.rewind((int) start);
1579 return false;
1582 DeclaratorAST *decl = 0;
1583 parseAbstractDeclarator(decl);
1585 TypeIdAST *ast = CreateNode<TypeIdAST>(_M_pool);
1586 ast->type_specifier = spec;
1587 ast->declarator = decl;
1589 UPDATE_POS(ast, start, token_stream.cursor());
1590 node = ast;
1592 return true;
1595 bool Parser::parseInitDeclaratorList(const ListNode<InitDeclaratorAST*> *&node)
1597 InitDeclaratorAST *decl = 0;
1598 if (!parseInitDeclarator(decl))
1599 return false;
1601 node = snoc(node, decl, _M_pool);
1603 while (token_stream.lookAhead() == ',')
1605 token_stream.nextToken();
1607 if (!parseInitDeclarator(decl))
1609 syntaxError();
1610 break;
1612 node = snoc(node, decl, _M_pool);
1615 return true;
1618 bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node)
1620 std::size_t start = token_stream.cursor();
1622 ParameterDeclarationClauseAST *ast
1623 = CreateNode<ParameterDeclarationClauseAST>(_M_pool);
1625 if (!parseParameterDeclarationList(ast->parameter_declarations))
1627 if (token_stream.lookAhead() == ')')
1628 goto good;
1630 if (token_stream.lookAhead() == Token_ellipsis
1631 && token_stream.lookAhead(1) == ')')
1633 ast->ellipsis = token_stream.cursor();
1634 goto good;
1637 return false;
1640 good:
1642 if (token_stream.lookAhead() == Token_ellipsis)
1644 ast->ellipsis = token_stream.cursor();
1645 token_stream.nextToken();
1648 /// @todo add ellipsis
1649 UPDATE_POS(ast, start, token_stream.cursor());
1650 node = ast;
1652 return true;
1655 bool Parser::parseParameterDeclarationList(const ListNode<ParameterDeclarationAST*> *&node)
1657 std::size_t start = token_stream.cursor();
1659 ParameterDeclarationAST *param = 0;
1660 if (!parseParameterDeclaration(param))
1662 token_stream.rewind((int) start);
1663 return false;
1666 node = snoc(node, param, _M_pool);
1668 while (token_stream.lookAhead() == ',')
1670 token_stream.nextToken();
1672 if (token_stream.lookAhead() == Token_ellipsis)
1673 break;
1675 if (!parseParameterDeclaration(param))
1677 token_stream.rewind((int) start);
1678 return false;
1680 node = snoc(node, param, _M_pool);
1683 return true;
1686 bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
1688 std::size_t start = token_stream.cursor();
1690 const ListNode<std::size_t> *storage = 0;
1691 parseStorageClassSpecifier(storage);
1693 // parse decl spec
1694 TypeSpecifierAST *spec = 0;
1695 if (!parseTypeSpecifier(spec))
1697 token_stream.rewind((int) start);
1698 return false;
1701 int index = (int) token_stream.cursor();
1703 DeclaratorAST *decl = 0;
1704 if (!parseDeclarator(decl))
1706 token_stream.rewind((int) index);
1708 // try with abstract declarator
1709 parseAbstractDeclarator(decl);
1712 ExpressionAST *expr = 0;
1713 if (token_stream.lookAhead() == '=')
1715 token_stream.nextToken();
1716 if (!parseLogicalOrExpression(expr,true))
1718 //reportError(("Expression expected"));
1722 ParameterDeclarationAST *ast = CreateNode<ParameterDeclarationAST>(_M_pool);
1723 ast->type_specifier = spec;
1724 ast->declarator = decl;
1725 ast->expression = expr;
1727 UPDATE_POS(ast, start, token_stream.cursor());
1728 node = ast;
1730 return true;
1733 bool Parser::parse_Attribute__() {
1734 token_stream.nextToken();
1736 ADVANCE('(', "(");
1738 ExpressionAST *expr = 0;
1739 parseExpression(expr);
1741 if (token_stream.lookAhead() != ')')
1743 reportError(("')' expected"));
1744 return false;
1746 else
1748 token_stream.nextToken();
1750 return true;
1753 QString Parser::tokenText(AST *ast) const
1755 if (ast == 0) return QString();
1757 int start_token = ast->start_token;
1758 int end_token = ast->end_token;
1760 Token const &tk = token_stream.token (start_token);
1761 Token const &end_tk = token_stream.token(end_token);
1763 return QString::fromLatin1 (&tk.text[tk.position],(int) (end_tk.position - tk.position)).trimmed();
1766 bool Parser::parseForwardDeclarationSpecifier(TypeSpecifierAST *&node)
1768 std::size_t start = token_stream.cursor();
1770 int kind = token_stream.lookAhead();
1771 if (kind != Token_class && kind != Token_struct && kind != Token_union)
1772 return false;
1774 std::size_t class_key = token_stream.cursor();
1775 token_stream.nextToken();
1777 NameAST *name = 0;
1778 if (!parseName(name, false)) {
1779 token_stream.rewind((int) start);
1780 return false;
1783 BaseClauseAST *bases = 0;
1784 if (token_stream.lookAhead() == ':')
1786 if (!parseBaseClause(bases))
1788 token_stream.rewind((int) start);
1789 return false;
1793 if (token_stream.lookAhead() != ';')
1795 token_stream.rewind((int) start);
1796 return false;
1799 ForwardDeclarationSpecifierAST *ast = CreateNode<ForwardDeclarationSpecifierAST>(_M_pool);
1800 ast->class_key = class_key;
1801 ast->name = name;
1802 ast->base_clause = bases;
1804 UPDATE_POS(ast, start, token_stream.cursor());
1805 node = ast;
1807 return true;
1810 bool Parser::parseClassSpecifier(TypeSpecifierAST *&node)
1812 std::size_t start = token_stream.cursor();
1814 int kind = token_stream.lookAhead();
1815 if (kind != Token_class && kind != Token_struct && kind != Token_union)
1816 return false;
1818 std::size_t class_key = token_stream.cursor();
1819 token_stream.nextToken();
1821 WinDeclSpecAST *winDeclSpec = 0;
1822 parseWinDeclSpec(winDeclSpec);
1824 if (token_stream.lookAhead() == Token___attribute__) {
1825 parse_Attribute__();
1828 while (token_stream.lookAhead() == Token_identifier
1829 && token_stream.lookAhead(1) == Token_identifier)
1831 token_stream.nextToken();
1834 NameAST *name = 0;
1835 parseName(name, true);
1837 BaseClauseAST *bases = 0;
1839 if (token_stream.lookAhead() == ':')
1841 if (!parseBaseClause(bases))
1843 skipUntil('{');
1847 if (token_stream.lookAhead() != '{')
1850 token_stream.rewind((int) start);
1851 return false;
1854 ADVANCE('{', "{");
1856 ClassSpecifierAST *ast = CreateNode<ClassSpecifierAST>(_M_pool);
1857 ast->win_decl_specifiers = winDeclSpec;
1858 ast->class_key = class_key;
1859 ast->name = name;
1860 ast->base_clause = bases;
1862 while (token_stream.lookAhead())
1864 if (token_stream.lookAhead() == '}')
1865 break;
1867 std::size_t startDecl = token_stream.cursor();
1869 DeclarationAST *memSpec = 0;
1870 if (!parseMemberSpecification(memSpec))
1872 if (startDecl == token_stream.cursor())
1873 token_stream.nextToken(); // skip at least one token
1874 skipUntilDeclaration();
1876 else
1877 ast->member_specs = snoc(ast->member_specs, memSpec, _M_pool);
1880 ADVANCE_NR('}', "}");
1882 UPDATE_POS(ast, start, token_stream.cursor());
1883 node = ast;
1885 return true;
1888 bool Parser::parseAccessSpecifier(DeclarationAST *&node)
1890 std::size_t start = token_stream.cursor();
1892 const ListNode<std::size_t> *specs = 0;
1894 bool done = false;
1895 while (!done)
1897 switch(token_stream.lookAhead())
1899 case Token_signals:
1900 case Token_slots:
1901 case Token_k_dcop:
1902 case Token_k_dcop_signals:
1903 case Token_public:
1904 case Token_protected:
1905 case Token_private:
1906 specs = snoc(specs, token_stream.cursor(), _M_pool);
1907 token_stream.nextToken();
1908 break;
1910 default:
1911 done = true;
1912 break;
1916 if (!specs)
1917 return false;
1919 ADVANCE(':', ":");
1921 AccessSpecifierAST *ast = CreateNode<AccessSpecifierAST>(_M_pool);
1922 ast->specs = specs;
1923 UPDATE_POS(ast, start, token_stream.cursor());
1924 node = ast;
1926 return true;
1929 bool Parser::parseMemberSpecification(DeclarationAST *&node)
1931 std::size_t start = token_stream.cursor();
1933 if (token_stream.lookAhead() == ';')
1935 token_stream.nextToken();
1936 return true;
1938 else if (token_stream.lookAhead() == Token_Q_OBJECT || token_stream.lookAhead() == Token_K_DCOP)
1940 token_stream.nextToken();
1941 return true;
1943 else if (parseTypedef(node))
1945 return true;
1947 else if (parseUsing(node))
1949 return true;
1951 else if (parseTemplateDeclaration(node))
1953 return true;
1955 else if (parseAccessSpecifier(node))
1957 return true;
1959 else if (parseQ_PROPERTY(node))
1961 return true;
1963 else if (parseQ_ENUMS(node))
1965 return true;
1968 token_stream.rewind((int) start);
1970 const ListNode<std::size_t> *cv = 0;
1971 parseCvQualify(cv);
1973 const ListNode<std::size_t> *storageSpec = 0;
1974 parseStorageClassSpecifier(storageSpec);
1976 parseCvQualify(cv);
1978 TypeSpecifierAST *spec = 0;
1979 if (parseEnumSpecifier(spec) || parseClassSpecifier(spec))
1981 parseCvQualify(cv);
1982 spec->cv = cv;
1984 const ListNode<InitDeclaratorAST*> *declarators = 0;
1985 parseInitDeclaratorList(declarators);
1986 ADVANCE(';', ";");
1988 SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool);
1989 ast->type_specifier = spec;
1990 ast->init_declarators = declarators;
1991 UPDATE_POS(ast, start, token_stream.cursor());
1992 node = ast;
1994 return true;
1997 token_stream.rewind((int) start);
1998 return parseDeclarationInternal(node);
2001 bool Parser::parseCtorInitializer(CtorInitializerAST *&node)
2003 std::size_t start = token_stream.cursor();
2005 CHECK(':');
2007 CtorInitializerAST *ast = CreateNode<CtorInitializerAST>(_M_pool);
2008 ast->colon = start;
2010 if (!parseMemInitializerList(ast->member_initializers))
2012 reportError(("Member initializers expected"));
2015 UPDATE_POS(ast, start, token_stream.cursor());
2016 node = ast;
2018 return true;
2021 bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST *&node)
2023 std::size_t start = token_stream.cursor();
2025 int tk = token_stream.lookAhead();
2026 if (tk == Token_class ||
2027 tk == Token_struct ||
2028 tk == Token_union ||
2029 tk == Token_enum ||
2030 tk == Token_typename)
2032 std::size_t type = token_stream.cursor();
2033 token_stream.nextToken();
2035 NameAST *name = 0;
2036 if (parseName(name, true))
2038 ElaboratedTypeSpecifierAST *ast
2039 = CreateNode<ElaboratedTypeSpecifierAST>(_M_pool);
2041 ast->type = type;
2042 ast->name = name;
2044 UPDATE_POS(ast, start, token_stream.cursor());
2045 node = ast;
2047 return true;
2051 token_stream.rewind((int) start);
2052 return false;
2055 bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node)
2057 std::size_t start = token_stream.cursor();
2059 CHECK(Token_throw);
2060 ADVANCE('(', "(");
2062 ExceptionSpecificationAST *ast
2063 = CreateNode<ExceptionSpecificationAST>(_M_pool);
2065 if (token_stream.lookAhead() == Token_ellipsis)
2067 ast->ellipsis = token_stream.cursor();
2068 token_stream.nextToken();
2070 else
2072 parseTypeIdList(ast->type_ids);
2075 ADVANCE(')', ")");
2077 UPDATE_POS(ast, start, token_stream.cursor());
2078 node = ast;
2080 return true;
2083 bool Parser::parseEnumerator(EnumeratorAST *&node)
2085 std::size_t start = token_stream.cursor();
2087 CHECK(Token_identifier);
2088 std::size_t id = token_stream.cursor() - 1;
2090 EnumeratorAST *ast = CreateNode<EnumeratorAST>(_M_pool);
2091 ast->id = id;
2093 if (token_stream.lookAhead() == '=')
2095 token_stream.nextToken();
2097 if (!parseConstantExpression(ast->expression))
2099 reportError(("Constant expression expected"));
2103 UPDATE_POS(ast, start, token_stream.cursor());
2104 node = ast;
2106 return true;
2109 bool Parser::parseInitDeclarator(InitDeclaratorAST *&node)
2111 std::size_t start = token_stream.cursor();
2113 DeclaratorAST *decl = 0;
2114 if (!parseDeclarator(decl))
2116 return false;
2119 if (token_stream.lookAhead(0) == Token_asm)
2121 token_stream.nextToken();
2122 skip('(', ')');
2123 token_stream.nextToken();
2126 InitializerAST *init = 0;
2127 parseInitializer(init);
2129 InitDeclaratorAST *ast = CreateNode<InitDeclaratorAST>(_M_pool);
2130 ast->declarator = decl;
2131 ast->initializer = init;
2133 UPDATE_POS(ast, start, token_stream.cursor());
2134 node = ast;
2136 return true;
2139 bool Parser::parseBaseClause(BaseClauseAST *&node)
2141 std::size_t start = token_stream.cursor();
2143 CHECK(':');
2145 BaseSpecifierAST *baseSpec = 0;
2146 if (!parseBaseSpecifier(baseSpec))
2147 return false;
2149 BaseClauseAST *ast = CreateNode<BaseClauseAST>(_M_pool);
2150 ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool);
2152 while (token_stream.lookAhead() == ',')
2154 token_stream.nextToken();
2156 if (!parseBaseSpecifier(baseSpec))
2158 reportError(("Base class specifier expected"));
2159 break;
2161 ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool);
2164 UPDATE_POS(ast, start, token_stream.cursor());
2165 node = ast;
2167 return true;
2170 bool Parser::parseInitializer(InitializerAST *&node)
2172 std::size_t start = token_stream.cursor();
2174 int tk = token_stream.lookAhead();
2175 if (tk != '=' && tk != '(')
2176 return false;
2178 InitializerAST *ast = CreateNode<InitializerAST>(_M_pool);
2180 if (tk == '=')
2182 token_stream.nextToken();
2184 if (!parseInitializerClause(ast->initializer_clause))
2186 reportError(("Initializer clause expected"));
2189 else if (tk == '(')
2191 token_stream.nextToken();
2192 parseCommaExpression(ast->expression);
2193 CHECK(')');
2196 UPDATE_POS(ast, start, token_stream.cursor());
2197 node = ast;
2199 return true;
2202 bool Parser::parseMemInitializerList(const ListNode<MemInitializerAST*> *&node)
2204 MemInitializerAST *init = 0;
2206 if (!parseMemInitializer(init))
2207 return false;
2209 node = snoc(node, init, _M_pool);
2211 while (token_stream.lookAhead() == ',')
2213 token_stream.nextToken();
2215 if (!parseMemInitializer(init))
2216 break;
2218 node = snoc(node, init, _M_pool);
2221 return true;
2224 bool Parser::parseMemInitializer(MemInitializerAST *&node)
2226 std::size_t start = token_stream.cursor();
2228 NameAST *initId = 0;
2229 if (!parseName(initId, true))
2231 reportError(("Identifier expected"));
2232 return false;
2235 ADVANCE('(', "(");
2236 ExpressionAST *expr = 0;
2237 parseCommaExpression(expr);
2238 ADVANCE(')', ")");
2240 MemInitializerAST *ast = CreateNode<MemInitializerAST>(_M_pool);
2241 ast->initializer_id = initId;
2242 ast->expression = expr;
2244 UPDATE_POS(ast, start, token_stream.cursor());
2245 node = ast;
2247 return true;
2250 bool Parser::parseTypeIdList(const ListNode<TypeIdAST*> *&node)
2252 TypeIdAST *typeId = 0;
2253 if (!parseTypeId(typeId))
2254 return false;
2256 node = snoc(node, typeId, _M_pool);
2258 while (token_stream.lookAhead() == ',')
2260 token_stream.nextToken();
2261 if (parseTypeId(typeId))
2263 node = snoc(node, typeId, _M_pool);
2265 else
2267 reportError(("Type id expected"));
2268 break;
2272 return true;
2275 bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node)
2277 std::size_t start = token_stream.cursor();
2279 BaseSpecifierAST *ast = CreateNode<BaseSpecifierAST>(_M_pool);
2281 if (token_stream.lookAhead() == Token_virtual)
2283 ast->virt = token_stream.cursor();
2284 token_stream.nextToken();
2286 int tk = token_stream.lookAhead();
2287 if (tk == Token_public || tk == Token_protected
2288 || tk == Token_private)
2290 ast->access_specifier = token_stream.cursor();
2291 token_stream.nextToken();
2294 else
2296 int tk = token_stream.lookAhead();
2297 if (tk == Token_public || tk == Token_protected
2298 || tk == Token_private)
2300 ast->access_specifier = token_stream.cursor();
2301 token_stream.nextToken();
2304 if (token_stream.lookAhead() == Token_virtual)
2306 ast->virt = token_stream.cursor();
2307 token_stream.nextToken();
2311 if (!parseName(ast->name, true))
2312 reportError(("Class name expected"));
2314 UPDATE_POS(ast, start, token_stream.cursor());
2315 node = ast;
2317 return true;
2320 bool Parser::parseInitializerClause(InitializerClauseAST *&node)
2322 std::size_t start = token_stream.cursor();
2324 InitializerClauseAST *ast = CreateNode<InitializerClauseAST>(_M_pool);
2326 if (token_stream.lookAhead() == '{')
2328 #if defined(__GNUC__)
2329 #warning "implement me"
2330 #endif
2331 if (skip('{','}'))
2332 token_stream.nextToken();
2333 else
2334 reportError(("} missing"));
2336 else
2338 if (!parseAssignmentExpression(ast->expression))
2340 //reportError(("Expression expected"));
2344 UPDATE_POS(ast, start, token_stream.cursor());
2345 node = ast;
2347 return true;
2350 bool Parser::parsePtrToMember(PtrToMemberAST *&node)
2352 #if defined(__GNUC__)
2353 #warning "implemente me (AST)"
2354 #endif
2356 std::size_t start = token_stream.cursor();
2358 std::size_t global_scope = 0;
2359 if (token_stream.lookAhead() == Token_scope)
2361 global_scope = token_stream.cursor();
2362 token_stream.nextToken();
2365 UnqualifiedNameAST *name = 0;
2366 while (token_stream.lookAhead() == Token_identifier)
2368 if (!parseUnqualifiedName(name))
2369 break;
2371 if (token_stream.lookAhead() == Token_scope
2372 && token_stream.lookAhead(1) == '*')
2374 token_stream.nextToken();
2375 token_stream.nextToken();
2377 PtrToMemberAST *ast = CreateNode<PtrToMemberAST>(_M_pool);
2378 UPDATE_POS(ast, start, token_stream.cursor());
2379 node = ast;
2381 return true;
2384 if (token_stream.lookAhead() == Token_scope)
2385 token_stream.nextToken();
2388 token_stream.rewind((int) start);
2389 return false;
2392 bool Parser::parseUnqualifiedName(UnqualifiedNameAST *&node,
2393 bool parseTemplateId)
2395 std::size_t start = token_stream.cursor();
2397 std::size_t tilde = 0;
2398 std::size_t id = 0;
2399 OperatorFunctionIdAST *operator_id = 0;
2401 if (token_stream.lookAhead() == Token_identifier)
2403 id = token_stream.cursor();
2404 token_stream.nextToken();
2406 else if (token_stream.lookAhead() == '~'
2407 && token_stream.lookAhead(1) == Token_identifier)
2409 tilde = token_stream.cursor();
2410 token_stream.nextToken(); // skip ~
2412 id = token_stream.cursor();
2413 token_stream.nextToken(); // skip classname
2415 else if (token_stream.lookAhead() == Token_operator)
2417 if (!parseOperatorFunctionId(operator_id))
2418 return false;
2420 else
2422 return false;
2425 UnqualifiedNameAST *ast = CreateNode<UnqualifiedNameAST>(_M_pool);
2426 ast->tilde = tilde;
2427 ast->id = id;
2428 ast->operator_id = operator_id;
2430 if (parseTemplateId && !tilde)
2432 std::size_t index = token_stream.cursor();
2434 if (token_stream.lookAhead() == '<')
2436 token_stream.nextToken();
2438 // optional template arguments
2439 parseTemplateArgumentList(ast->template_arguments);
2441 if (token_stream.lookAhead() == '>')
2443 token_stream.nextToken();
2445 else
2447 ast->template_arguments = 0;
2448 token_stream.rewind((int) index);
2453 UPDATE_POS(ast, start, token_stream.cursor());
2454 node = ast;
2456 return true;
2459 bool Parser::parseStringLiteral(StringLiteralAST *&node)
2461 std::size_t start = token_stream.cursor();
2463 if (token_stream.lookAhead() != Token_string_literal)
2464 return false;
2466 StringLiteralAST *ast = CreateNode<StringLiteralAST>(_M_pool);
2468 while (token_stream.lookAhead() == Token_string_literal)
2470 ast->literals = snoc(ast->literals, token_stream.cursor(), _M_pool);
2471 token_stream.nextToken();
2474 UPDATE_POS(ast, start, token_stream.cursor());
2475 node = ast;
2477 return true;
2480 bool Parser::parseExpressionStatement(StatementAST *&node)
2482 std::size_t start = token_stream.cursor();
2484 ExpressionAST *expr = 0;
2485 parseCommaExpression(expr);
2487 ADVANCE(';', ";");
2489 ExpressionStatementAST *ast = CreateNode<ExpressionStatementAST>(_M_pool);
2490 ast->expression = expr;
2492 UPDATE_POS(ast, start, token_stream.cursor());
2493 node = ast;
2495 return true;
2498 bool Parser::parseStatement(StatementAST *&node)
2500 std::size_t start = token_stream.cursor();
2502 switch(token_stream.lookAhead())
2504 case Token_while:
2505 return parseWhileStatement(node);
2507 case Token_do:
2508 return parseDoStatement(node);
2510 case Token_for:
2511 return parseForStatement(node);
2513 case Token_if:
2514 return parseIfStatement(node);
2516 case Token_switch:
2517 return parseSwitchStatement(node);
2519 case Token_try:
2520 return parseTryBlockStatement(node);
2522 case Token_case:
2523 case Token_default:
2524 return parseLabeledStatement(node);
2526 case Token_break:
2527 case Token_continue:
2528 #if defined(__GNUC__)
2529 #warning "implement me"
2530 #endif
2531 token_stream.nextToken();
2532 ADVANCE(';', ";");
2533 return true;
2535 case Token_goto:
2536 #if defined(__GNUC__)
2537 #warning "implement me"
2538 #endif
2539 token_stream.nextToken();
2540 ADVANCE(Token_identifier, "identifier");
2541 ADVANCE(';', ";");
2542 return true;
2544 case Token_return:
2546 token_stream.nextToken();
2547 ExpressionAST *expr = 0;
2548 parseCommaExpression(expr);
2550 ADVANCE(';', ";");
2552 ReturnStatementAST *ast = CreateNode<ReturnStatementAST>(_M_pool);
2553 ast->expression = expr;
2555 UPDATE_POS(ast, start, token_stream.cursor());
2556 node = ast;
2558 return true;
2560 case '{':
2561 return parseCompoundStatement(node);
2563 case Token_identifier:
2564 if (parseLabeledStatement(node))
2565 return true;
2566 break;
2569 return parseExpressionOrDeclarationStatement(node);
2572 bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
2574 bool blocked = block_errors(true);
2576 std::size_t start = token_stream.cursor();
2578 StatementAST *decl_ast = 0;
2579 bool maybe_amb = parseDeclarationStatement(decl_ast);
2580 maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';';
2582 std::size_t end = token_stream.cursor();
2584 token_stream.rewind((int) start);
2585 StatementAST *expr_ast = 0;
2586 maybe_amb &= parseExpressionStatement(expr_ast);
2587 maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';';
2589 if (maybe_amb)
2591 Q_ASSERT(decl_ast != 0 && expr_ast != 0);
2592 ExpressionOrDeclarationStatementAST *ast
2593 = CreateNode<ExpressionOrDeclarationStatementAST>(_M_pool);
2594 ast->declaration = decl_ast;
2595 ast->expression = expr_ast;
2597 UPDATE_POS(ast, start, token_stream.cursor());
2598 node = ast;
2600 else
2602 token_stream.rewind((int) std::max(end, token_stream.cursor()));
2604 node = decl_ast;
2605 if (!node)
2606 node = expr_ast;
2609 block_errors(blocked);
2611 if (!node)
2612 syntaxError();
2614 return node != 0;
2617 bool Parser::parseCondition(ConditionAST *&node, bool initRequired)
2619 std::size_t start = token_stream.cursor();
2621 ConditionAST *ast = CreateNode<ConditionAST>(_M_pool);
2622 TypeSpecifierAST *spec = 0;
2624 if (parseTypeSpecifier(spec))
2626 ast->type_specifier = spec;
2628 std::size_t declarator_start = token_stream.cursor();
2630 DeclaratorAST *decl = 0;
2631 if (!parseDeclarator(decl))
2633 token_stream.rewind((int) declarator_start);
2634 if (!initRequired && !parseAbstractDeclarator(decl))
2635 decl = 0;
2638 if (decl && (!initRequired || token_stream.lookAhead() == '='))
2640 ast->declarator = decl;
2642 if (token_stream.lookAhead() == '=')
2644 token_stream.nextToken();
2646 parseExpression(ast->expression);
2649 UPDATE_POS(ast, start, token_stream.cursor());
2650 node = ast;
2652 return true;
2656 token_stream.rewind((int) start);
2658 if (!parseCommaExpression(ast->expression))
2659 return false;
2661 UPDATE_POS(ast, start, token_stream.cursor());
2662 node = ast;
2664 return true;
2668 bool Parser::parseWhileStatement(StatementAST *&node)
2670 std::size_t start = token_stream.cursor();
2672 ADVANCE(Token_while, "while");
2673 ADVANCE('(' , "(");
2675 ConditionAST *cond = 0;
2676 if (!parseCondition(cond))
2678 reportError(("condition expected"));
2679 return false;
2681 ADVANCE(')', ")");
2683 StatementAST *body = 0;
2684 if (!parseStatement(body))
2686 reportError(("statement expected"));
2687 return false;
2690 WhileStatementAST *ast = CreateNode<WhileStatementAST>(_M_pool);
2691 ast->condition = cond;
2692 ast->statement = body;
2694 UPDATE_POS(ast, start, token_stream.cursor());
2695 node = ast;
2697 return true;
2700 bool Parser::parseDoStatement(StatementAST *&node)
2702 std::size_t start = token_stream.cursor();
2704 ADVANCE(Token_do, "do");
2706 StatementAST *body = 0;
2707 if (!parseStatement(body))
2709 reportError(("statement expected"));
2710 //return false;
2713 ADVANCE_NR(Token_while, "while");
2714 ADVANCE_NR('(' , "(");
2716 ExpressionAST *expr = 0;
2717 if (!parseCommaExpression(expr))
2719 reportError(("expression expected"));
2720 //return false;
2723 ADVANCE_NR(')', ")");
2724 ADVANCE_NR(';', ";");
2726 DoStatementAST *ast = CreateNode<DoStatementAST>(_M_pool);
2727 ast->statement = body;
2728 ast->expression = expr;
2730 UPDATE_POS(ast, start, token_stream.cursor());
2731 node = ast;
2733 return true;
2736 bool Parser::parseForStatement(StatementAST *&node)
2738 std::size_t start = token_stream.cursor();
2740 ADVANCE(Token_for, "for");
2741 ADVANCE('(', "(");
2743 StatementAST *init = 0;
2744 if (!parseForInitStatement(init))
2746 reportError(("for initialization expected"));
2747 return false;
2750 ConditionAST *cond = 0;
2751 parseCondition(cond);
2752 ADVANCE(';', ";");
2754 ExpressionAST *expr = 0;
2755 parseCommaExpression(expr);
2756 ADVANCE(')', ")");
2758 StatementAST *body = 0;
2759 if (!parseStatement(body))
2760 return false;
2762 ForStatementAST *ast = CreateNode<ForStatementAST>(_M_pool);
2763 ast->init_statement = init;
2764 ast->condition = cond;
2765 ast->expression = expr;
2766 ast->statement = body;
2768 UPDATE_POS(ast, start, token_stream.cursor());
2769 node = ast;
2771 return true;
2774 bool Parser::parseForInitStatement(StatementAST *&node)
2776 if (parseDeclarationStatement(node))
2777 return true;
2779 return parseExpressionStatement(node);
2782 bool Parser::parseCompoundStatement(StatementAST *&node)
2784 std::size_t start = token_stream.cursor();
2786 CHECK('{');
2788 CompoundStatementAST *ast = CreateNode<CompoundStatementAST>(_M_pool);
2790 while (token_stream.lookAhead())
2792 if (token_stream.lookAhead() == '}')
2793 break;
2795 std::size_t startStmt = token_stream.cursor();
2797 StatementAST *stmt = 0;
2798 if (!parseStatement(stmt))
2800 if (startStmt == token_stream.cursor())
2801 token_stream.nextToken();
2803 skipUntilStatement();
2805 else
2807 ast->statements = snoc(ast->statements, stmt, _M_pool);
2811 ADVANCE_NR('}', "}");
2813 UPDATE_POS(ast, start, token_stream.cursor());
2814 node = ast;
2816 return true;
2819 bool Parser::parseIfStatement(StatementAST *&node)
2821 std::size_t start = token_stream.cursor();
2823 ADVANCE(Token_if, "if");
2825 ADVANCE('(' , "(");
2827 IfStatementAST *ast = CreateNode<IfStatementAST>(_M_pool);
2829 ConditionAST *cond = 0;
2830 if (!parseCondition(cond))
2832 reportError(("condition expected"));
2833 return false;
2835 ADVANCE(')', ")");
2837 StatementAST *stmt = 0;
2838 if (!parseStatement(stmt))
2840 reportError(("statement expected"));
2841 return false;
2844 ast->condition = cond;
2845 ast->statement = stmt;
2847 if (token_stream.lookAhead() == Token_else)
2849 token_stream.nextToken();
2851 if (!parseStatement(ast->else_statement))
2853 reportError(("statement expected"));
2854 return false;
2858 UPDATE_POS(ast, start, token_stream.cursor());
2859 node = ast;
2861 return true;
2864 bool Parser::parseSwitchStatement(StatementAST *&node)
2866 std::size_t start = token_stream.cursor();
2867 ADVANCE(Token_switch, "switch");
2869 ADVANCE('(' , "(");
2871 ConditionAST *cond = 0;
2872 if (!parseCondition(cond))
2874 reportError(("condition expected"));
2875 return false;
2877 ADVANCE(')', ")");
2879 StatementAST *stmt = 0;
2880 if (!parseCompoundStatement(stmt))
2882 syntaxError();
2883 return false;
2886 SwitchStatementAST *ast = CreateNode<SwitchStatementAST>(_M_pool);
2887 ast->condition = cond;
2888 ast->statement = stmt;
2890 UPDATE_POS(ast, start, token_stream.cursor());
2891 node = ast;
2893 return true;
2896 bool Parser::parseLabeledStatement(StatementAST *&node)
2898 switch(token_stream.lookAhead())
2900 case Token_identifier:
2901 case Token_default:
2902 if (token_stream.lookAhead(1) == ':')
2904 token_stream.nextToken();
2905 token_stream.nextToken();
2907 StatementAST *stmt = 0;
2908 if (parseStatement(stmt))
2910 node = stmt;
2911 return true;
2914 break;
2916 case Token_case:
2918 token_stream.nextToken();
2919 ExpressionAST *expr = 0;
2920 if (!parseConstantExpression(expr))
2922 reportError(("expression expected"));
2924 else if (token_stream.lookAhead() == Token_ellipsis)
2926 token_stream.nextToken();
2928 ExpressionAST *expr2 = 0;
2929 if (!parseConstantExpression(expr2))
2931 reportError(("expression expected"));
2934 ADVANCE(':', ":");
2936 StatementAST *stmt = 0;
2937 if (parseStatement(stmt))
2939 node = stmt;
2940 return true;
2943 break;
2947 return false;
2950 bool Parser::parseBlockDeclaration(DeclarationAST *&node)
2952 switch(token_stream.lookAhead())
2954 case Token_typedef:
2955 return parseTypedef(node);
2956 case Token_using:
2957 return parseUsing(node);
2958 case Token_asm:
2959 return parseAsmDefinition(node);
2960 case Token_namespace:
2961 return parseNamespaceAliasDefinition(node);
2964 std::size_t start = token_stream.cursor();
2966 const ListNode<std::size_t> *cv = 0;
2967 parseCvQualify(cv);
2969 const ListNode<std::size_t> *storageSpec = 0;
2970 parseStorageClassSpecifier(storageSpec);
2972 parseCvQualify(cv);
2974 TypeSpecifierAST *spec = 0;
2975 if (!parseTypeSpecifierOrClassSpec(spec))
2976 { // replace with simpleTypeSpecifier?!?!
2977 token_stream.rewind((int) start);
2978 return false;
2981 parseCvQualify(cv);
2982 spec->cv = cv;
2984 const ListNode<InitDeclaratorAST*> *declarators = 0;
2985 parseInitDeclaratorList(declarators);
2987 if (token_stream.lookAhead() != ';')
2989 token_stream.rewind((int) start);
2990 return false;
2992 token_stream.nextToken();
2994 SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool);
2995 ast->type_specifier = spec;
2996 ast->init_declarators = declarators;
2998 UPDATE_POS(ast, start, token_stream.cursor());
2999 node = ast;
3001 return true;
3004 bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node)
3006 std::size_t start = token_stream.cursor();
3008 CHECK(Token_namespace);
3010 NamespaceAliasDefinitionAST *ast
3011 = CreateNode<NamespaceAliasDefinitionAST>(_M_pool);
3013 ADVANCE(Token_identifier, "identifier");
3014 ast->namespace_name = token_stream.cursor() - 1;
3016 ADVANCE('=', "=");
3018 if (!parseName(ast->alias_name))
3020 reportError(("Namespace name expected"));
3023 ADVANCE(';', ";");
3025 UPDATE_POS(ast, start, token_stream.cursor());
3026 node = ast;
3028 return true;
3031 bool Parser::parseDeclarationStatement(StatementAST *&node)
3033 std::size_t start = token_stream.cursor();
3035 DeclarationAST *decl = 0;
3036 if (!parseBlockDeclaration(decl))
3037 return false;
3039 DeclarationStatementAST *ast = CreateNode<DeclarationStatementAST>(_M_pool);
3040 ast->declaration = decl;
3042 UPDATE_POS(ast, start, token_stream.cursor());
3043 node = ast;
3045 return true;
3048 bool Parser::parseDeclarationInternal(DeclarationAST *&node)
3050 std::size_t start = token_stream.cursor();
3052 // that is for the case '__declspec(dllexport) int ...' or
3053 // '__declspec(dllexport) inline int ...', etc.
3054 WinDeclSpecAST *winDeclSpec = 0;
3055 parseWinDeclSpec(winDeclSpec);
3057 const ListNode<std::size_t> *funSpec = 0;
3058 bool hasFunSpec = parseFunctionSpecifier(funSpec);
3060 const ListNode<std::size_t> *cv = 0;
3061 parseCvQualify(cv);
3063 const ListNode<std::size_t> *storageSpec = 0;
3064 bool hasStorageSpec = parseStorageClassSpecifier(storageSpec);
3066 if (hasStorageSpec && !hasFunSpec)
3067 hasFunSpec = parseFunctionSpecifier(funSpec);
3069 // that is for the case 'friend __declspec(dllexport) ....'
3070 parseWinDeclSpec(winDeclSpec);
3072 if (!cv)
3073 parseCvQualify(cv);
3075 int index = (int) token_stream.cursor();
3076 NameAST *name = 0;
3077 if (parseName(name, true) && token_stream.lookAhead() == '(')
3079 // no type specifier, maybe a constructor or a cast operator??
3081 token_stream.rewind((int) index);
3083 InitDeclaratorAST *declarator = 0;
3084 if (parseInitDeclarator(declarator))
3086 switch(token_stream.lookAhead())
3088 case ';':
3090 token_stream.nextToken();
3092 SimpleDeclarationAST *ast
3093 = CreateNode<SimpleDeclarationAST>(_M_pool);
3095 ast->storage_specifiers = storageSpec;
3096 ast->function_specifiers = funSpec;
3097 ast->init_declarators = snoc(ast->init_declarators,
3098 declarator, _M_pool);
3100 UPDATE_POS(ast, start, token_stream.cursor());
3101 node = ast;
3103 return true;
3105 case ':':
3107 CtorInitializerAST *ctorInit = 0;
3108 StatementAST *funBody = 0;
3110 if (parseCtorInitializer(ctorInit)
3111 && parseFunctionBody(funBody))
3113 FunctionDefinitionAST *ast
3114 = CreateNode<FunctionDefinitionAST>(_M_pool);
3116 ast->storage_specifiers = storageSpec;
3117 ast->function_specifiers = funSpec;
3118 ast->init_declarator = declarator;
3119 ast->function_body = funBody;
3121 UPDATE_POS(ast, start, token_stream.cursor());
3122 node = ast;
3124 return true;
3127 break;
3129 case '{':
3131 StatementAST *funBody = 0;
3132 if (parseFunctionBody(funBody))
3134 FunctionDefinitionAST *ast
3135 = CreateNode<FunctionDefinitionAST>(_M_pool);
3137 ast->storage_specifiers = storageSpec;
3138 ast->function_specifiers = funSpec;
3139 ast->init_declarator = declarator;
3140 ast->function_body = funBody;
3142 UPDATE_POS(ast, start, token_stream.cursor());
3143 node = ast;
3145 return true;
3148 break;
3150 case '(':
3151 case '[':
3152 // ops!! it seems a declarator
3153 goto start_decl;
3154 break;
3160 start_decl:
3161 token_stream.rewind((int) index);
3163 if (token_stream.lookAhead() == Token_const
3164 && token_stream.lookAhead(1) == Token_identifier
3165 && token_stream.lookAhead(2) == '=')
3167 // constant definition
3168 token_stream.nextToken(); // skip const
3170 const ListNode<InitDeclaratorAST*> *declarators = 0;
3171 if (!parseInitDeclaratorList(declarators))
3173 syntaxError();
3174 return false;
3177 ADVANCE(';', ";");
3179 #if defined(__GNUC__)
3180 #warning "mark the ast as constant"
3181 #endif
3182 SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(_M_pool);
3183 ast->init_declarators = declarators;
3185 UPDATE_POS(ast, start, token_stream.cursor());
3186 node = ast;
3188 return true;
3191 TypeSpecifierAST *spec = 0;
3192 if (parseTypeSpecifier(spec))
3194 Q_ASSERT(spec != 0);
3196 if (!hasFunSpec)
3197 parseFunctionSpecifier(funSpec); // e.g. "void inline"
3199 spec->cv = cv;
3201 const ListNode<InitDeclaratorAST*> *declarators = 0;
3202 InitDeclaratorAST *decl = 0;
3203 int startDeclarator = (int) token_stream.cursor();
3204 bool maybeFunctionDefinition = false;
3206 if (token_stream.lookAhead() != ';')
3208 if (parseInitDeclarator(decl) && token_stream.lookAhead() == '{')
3210 // function definition
3211 maybeFunctionDefinition = true;
3213 else
3215 token_stream.rewind((int) startDeclarator);
3216 if (!parseInitDeclaratorList(declarators))
3218 syntaxError();
3219 return false;
3224 switch(token_stream.lookAhead())
3226 case ';':
3228 token_stream.nextToken();
3229 SimpleDeclarationAST *ast
3230 = CreateNode<SimpleDeclarationAST>(_M_pool);
3232 ast->storage_specifiers = storageSpec;
3233 ast->function_specifiers = funSpec;
3234 ast->type_specifier = spec;
3235 ast->win_decl_specifiers = winDeclSpec;
3236 ast->init_declarators = declarators;
3238 UPDATE_POS(ast, start, token_stream.cursor());
3239 node = ast;
3241 return true;
3243 case '{':
3245 if (!maybeFunctionDefinition)
3247 syntaxError();
3248 return false;
3251 StatementAST *funBody = 0;
3252 if (parseFunctionBody(funBody))
3254 FunctionDefinitionAST *ast
3255 = CreateNode<FunctionDefinitionAST>(_M_pool);
3257 ast->win_decl_specifiers = winDeclSpec;
3258 ast->storage_specifiers = storageSpec;
3259 ast->function_specifiers = funSpec;
3260 ast->type_specifier = spec;
3261 ast->init_declarator = decl;
3262 ast->function_body = funBody;
3264 UPDATE_POS(ast, start, token_stream.cursor());
3265 node = ast;
3267 return true;
3270 break;
3271 } // end switch
3274 syntaxError();
3275 return false;
3278 bool Parser::skipFunctionBody(StatementAST *&)
3280 #if defined(__GNUC__)
3281 #warning "Parser::skipFunctionBody() -- implement me"
3282 #endif
3283 Q_ASSERT(0); // ### not implemented
3284 return 0;
3287 bool Parser::parseFunctionBody(StatementAST *&node)
3289 if (control->skipFunctionBody())
3290 return skipFunctionBody(node);
3292 return parseCompoundStatement(node);
3295 bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node)
3297 if (parseClassSpecifier(node))
3298 return true;
3299 else if (parseEnumSpecifier(node))
3300 return true;
3301 else if (parseTypeSpecifier(node))
3302 return true;
3304 return false;
3307 bool Parser::parseTryBlockStatement(StatementAST *&node)
3309 #if defined(__GNUC__)
3310 #warning "implement me"
3311 #endif
3312 CHECK(Token_try);
3314 StatementAST *stmt = 0;
3315 if (!parseCompoundStatement(stmt))
3317 syntaxError();
3318 return false;
3321 if (token_stream.lookAhead() != Token_catch)
3323 reportError(("catch expected"));
3324 return false;
3327 while (token_stream.lookAhead() == Token_catch)
3329 token_stream.nextToken();
3330 ADVANCE('(', "(");
3331 ConditionAST *cond = 0;
3332 if (token_stream.lookAhead() == Token_ellipsis)
3334 token_stream.nextToken();
3336 else if (!parseCondition(cond, false))
3338 reportError(("condition expected"));
3339 return false;
3341 ADVANCE(')', ")");
3343 StatementAST *body = 0;
3344 if (!parseCompoundStatement(body))
3346 syntaxError();
3347 return false;
3351 node = stmt;
3352 return true;
3355 bool Parser::parsePrimaryExpression(ExpressionAST *&node)
3357 std::size_t start = token_stream.cursor();
3359 PrimaryExpressionAST *ast = CreateNode<PrimaryExpressionAST>(_M_pool);
3361 switch(token_stream.lookAhead())
3363 case Token_string_literal:
3364 parseStringLiteral(ast->literal);
3365 break;
3367 case Token_number_literal:
3368 case Token_char_literal:
3369 case Token_true:
3370 case Token_false:
3371 case Token_this:
3372 ast->token = token_stream.cursor();
3373 token_stream.nextToken();
3374 break;
3376 case '(':
3377 token_stream.nextToken();
3379 if (token_stream.lookAhead() == '{')
3381 if (!parseCompoundStatement(ast->expression_statement))
3382 return false;
3384 else
3386 if (!parseExpression(ast->sub_expression))
3387 return false;
3390 CHECK(')');
3391 break;
3393 default:
3394 if (!parseName(ast->name))
3395 return false;
3397 break;
3400 UPDATE_POS(ast, start, token_stream.cursor());
3401 node = ast;
3403 return true;
3408 postfix-expression-internal:
3409 [ expression ]
3410 ( expression-list [opt] )
3411 (.|->) template [opt] id-expression
3412 (.|->) pseudo-destructor-name
3416 bool Parser::parsePostfixExpressionInternal(ExpressionAST *&node)
3418 std::size_t start = token_stream.cursor();
3420 switch (token_stream.lookAhead())
3422 case '[':
3424 token_stream.nextToken();
3425 ExpressionAST *expr = 0;
3426 parseExpression(expr);
3427 CHECK(']');
3429 SubscriptExpressionAST *ast
3430 = CreateNode<SubscriptExpressionAST>(_M_pool);
3432 ast->subscript = expr;
3434 UPDATE_POS(ast, start, token_stream.cursor());
3435 node = ast;
3437 return true;
3439 case '(':
3441 token_stream.nextToken();
3442 ExpressionAST *expr = 0;
3443 parseExpression(expr);
3444 CHECK(')');
3446 FunctionCallAST *ast = CreateNode<FunctionCallAST>(_M_pool);
3447 ast->arguments = expr;
3449 UPDATE_POS(ast, start, token_stream.cursor());
3450 node = ast;
3452 return true;
3454 case '.':
3455 case Token_arrow:
3457 std::size_t op = token_stream.cursor();
3458 token_stream.nextToken();
3460 std::size_t templ = 0;
3461 if (token_stream.lookAhead() == Token_template)
3463 templ = token_stream.cursor();
3464 token_stream.nextToken();
3467 int saved = int(token_stream.cursor());
3468 NameAST *name = 0;
3470 if (parseName(name, true) && name->unqualified_name
3471 && name->unqualified_name->template_arguments != 0
3472 && token_stream.lookAhead() == '(') {
3473 // a template method call
3474 // ### reverse the logic
3475 } else {
3476 token_stream.rewind(saved);
3477 name = 0;
3479 if (! parseName (name, templ != 0))
3480 return false;
3483 ClassMemberAccessAST *ast = CreateNode<ClassMemberAccessAST>(_M_pool);
3484 ast->op = op;
3485 ast->name = name;
3487 UPDATE_POS(ast, start, token_stream.cursor());
3488 node = ast;
3490 return true;
3492 case Token_incr:
3493 case Token_decr:
3495 std::size_t op = token_stream.cursor();
3496 token_stream.nextToken();
3498 IncrDecrExpressionAST *ast = CreateNode<IncrDecrExpressionAST>(_M_pool);
3499 ast->op = op;
3501 UPDATE_POS(ast, start, token_stream.cursor());
3502 node = ast;
3504 return true;
3506 default:
3507 return false;
3512 postfix-expression:
3513 simple-type-specifier ( expression-list [opt] )
3514 primary-expression postfix-expression-internal*
3516 bool Parser::parsePostfixExpression(ExpressionAST *&node)
3518 std::size_t start = token_stream.cursor();
3520 switch (token_stream.lookAhead())
3522 case Token_dynamic_cast:
3523 case Token_static_cast:
3524 case Token_reinterpret_cast:
3525 case Token_const_cast:
3527 std::size_t castOp = token_stream.cursor();
3528 token_stream.nextToken();
3530 CHECK('<');
3531 TypeIdAST *typeId = 0;
3532 parseTypeId(typeId);
3533 CHECK('>');
3535 CHECK('(');
3536 ExpressionAST *expr = 0;
3537 parseCommaExpression(expr);
3538 CHECK(')');
3540 CppCastExpressionAST *ast = CreateNode<CppCastExpressionAST>(_M_pool);
3541 ast->op = castOp;
3542 ast->type_id = typeId;
3543 ast->expression = expr;
3545 ExpressionAST *e = 0;
3546 while (parsePostfixExpressionInternal(e))
3548 ast->sub_expressions = snoc(ast->sub_expressions, e, _M_pool);
3551 UPDATE_POS(ast, start, token_stream.cursor());
3552 node = ast;
3554 return true;
3556 case Token_typename:
3558 std::size_t token = token_stream.cursor();
3559 token_stream.nextToken();
3561 NameAST* name = 0;
3562 if (!parseName(name, true))
3563 return false;
3565 CHECK('(');
3566 ExpressionAST *expr = 0;
3567 parseCommaExpression(expr);
3568 CHECK(')');
3570 TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(_M_pool);
3571 ast->typename_token = token;
3572 ast->name = name;
3573 ast->expression = expr;
3575 UPDATE_POS(ast, start, token_stream.cursor());
3576 node = ast;
3578 return true;
3580 case Token_typeid:
3582 token_stream.nextToken();
3584 CHECK('(');
3585 TypeIdAST *typeId = 0;
3586 parseTypeId(typeId);
3587 CHECK(')');
3589 TypeIdentificationAST *ast = CreateNode<TypeIdentificationAST>(_M_pool);
3590 UPDATE_POS(ast, start, token_stream.cursor());
3591 node = ast;
3593 return true;
3595 default:
3596 break;
3599 std::size_t saved_pos = token_stream.cursor();
3601 TypeSpecifierAST *typeSpec = 0;
3602 ExpressionAST *expr = 0;
3604 // let's try to parse a type
3605 NameAST *name = 0;
3606 if (parseName(name, true))
3608 Q_ASSERT(name->unqualified_name != 0);
3610 bool has_template_args
3611 = name->unqualified_name->template_arguments != 0;
3613 if (has_template_args && token_stream.lookAhead() == '(')
3615 ExpressionAST *cast_expr = 0;
3616 if (parseCastExpression(cast_expr)
3617 && cast_expr->kind == AST::Kind_CastExpression)
3619 token_stream.rewind((int) saved_pos);
3620 parsePrimaryExpression(expr);
3621 goto L_no_rewind;
3626 token_stream.rewind((int) saved_pos);
3628 L_no_rewind:
3629 if (!expr && parseSimpleTypeSpecifier(typeSpec)
3630 && token_stream.lookAhead() == '(')
3632 token_stream.nextToken(); // skip '('
3633 parseCommaExpression(expr);
3634 CHECK(')');
3636 else if (expr)
3638 typeSpec = 0;
3640 else
3642 typeSpec = 0;
3643 token_stream.rewind((int) start);
3645 if (!parsePrimaryExpression(expr))
3646 return false;
3649 const ListNode<ExpressionAST*> *sub_expressions = 0;
3650 ExpressionAST *sub_expression = 0;
3652 while (parsePostfixExpressionInternal(sub_expression))
3653 sub_expressions = snoc(sub_expressions, sub_expression, _M_pool);
3655 if (sub_expressions || ! expr || (typeSpec && expr))
3657 PostfixExpressionAST *ast = CreateNode<PostfixExpressionAST>(_M_pool);
3658 ast->type_specifier = typeSpec;
3659 ast->expression = expr;
3660 ast->sub_expressions = sub_expressions;
3662 UPDATE_POS(ast, start, token_stream.cursor());
3663 node = ast;
3665 else
3666 node = expr;
3668 return true;
3671 bool Parser::parseUnaryExpression(ExpressionAST *&node)
3673 std::size_t start = token_stream.cursor();
3675 switch(token_stream.lookAhead())
3677 case Token_incr:
3678 case Token_decr:
3679 case '*':
3680 case '&':
3681 case '+':
3682 case '-':
3683 case '!':
3684 case '~':
3686 std::size_t op = token_stream.cursor();
3687 token_stream.nextToken();
3689 ExpressionAST *expr = 0;
3690 if (!parseCastExpression(expr))
3691 return false;
3693 UnaryExpressionAST *ast = CreateNode<UnaryExpressionAST>(_M_pool);
3694 ast->op = op;
3695 ast->expression = expr;
3697 UPDATE_POS(ast, start, token_stream.cursor());
3698 node = ast;
3700 return true;
3702 case Token_sizeof:
3704 std::size_t sizeof_token = token_stream.cursor();
3705 token_stream.nextToken();
3707 SizeofExpressionAST *ast = CreateNode<SizeofExpressionAST>(_M_pool);
3708 ast->sizeof_token = sizeof_token;
3710 std::size_t index = token_stream.cursor();
3711 if (token_stream.lookAhead() == '(')
3713 token_stream.nextToken();
3714 if (parseTypeId(ast->type_id) && token_stream.lookAhead() == ')')
3716 token_stream.nextToken(); // skip )
3718 UPDATE_POS(ast, start, token_stream.cursor());
3719 node = ast;
3720 return true;
3723 ast->type_id = 0;
3724 token_stream.rewind((int) index);
3727 if (!parseUnaryExpression(ast->expression))
3728 return false;
3730 UPDATE_POS(ast, start, token_stream.cursor());
3731 node = ast;
3732 return true;
3735 default:
3736 break;
3739 int token = token_stream.lookAhead();
3741 if (token == Token_new
3742 || (token == Token_scope && token_stream.lookAhead(1) == Token_new))
3743 return parseNewExpression(node);
3745 if (token == Token_delete
3746 || (token == Token_scope && token_stream.lookAhead(1) == Token_delete))
3747 return parseDeleteExpression(node);
3749 return parsePostfixExpression(node);
3752 bool Parser::parseNewExpression(ExpressionAST *&node)
3754 std::size_t start = token_stream.cursor();
3756 NewExpressionAST *ast = CreateNode<NewExpressionAST>(_M_pool);
3758 if (token_stream.lookAhead() == Token_scope
3759 && token_stream.lookAhead(1) == Token_new)
3761 ast->scope_token = token_stream.cursor();
3762 token_stream.nextToken();
3765 CHECK(Token_new);
3766 ast->new_token = token_stream.cursor() - 1;
3768 if (token_stream.lookAhead() == '(')
3770 token_stream.nextToken();
3771 parseCommaExpression(ast->expression);
3772 CHECK(')');
3775 if (token_stream.lookAhead() == '(')
3777 token_stream.nextToken();
3778 parseTypeId(ast->type_id);
3779 CHECK(')');
3781 else
3783 parseNewTypeId(ast->new_type_id);
3786 parseNewInitializer(ast->new_initializer);
3788 UPDATE_POS(ast, start, token_stream.cursor());
3789 node = ast;
3791 return true;
3794 bool Parser::parseNewTypeId(NewTypeIdAST *&node)
3796 std::size_t start = token_stream.cursor();
3798 TypeSpecifierAST *typeSpec = 0;
3799 if (!parseTypeSpecifier(typeSpec))
3800 return false;
3802 NewTypeIdAST *ast = CreateNode<NewTypeIdAST>(_M_pool);
3803 ast->type_specifier = typeSpec;
3805 parseNewDeclarator(ast->new_declarator);
3807 UPDATE_POS(ast, start, token_stream.cursor());
3808 node = ast;
3810 return true;
3813 bool Parser::parseNewDeclarator(NewDeclaratorAST *&node)
3815 std::size_t start = token_stream.cursor();
3817 NewDeclaratorAST *ast = CreateNode<NewDeclaratorAST>(_M_pool);
3819 PtrOperatorAST *ptrOp = 0;
3820 if (parsePtrOperator(ptrOp))
3822 ast->ptr_op = ptrOp;
3823 parseNewDeclarator(ast->sub_declarator);
3826 while (token_stream.lookAhead() == '[')
3828 token_stream.nextToken();
3829 ExpressionAST *expr = 0;
3830 parseExpression(expr);
3831 ast->expressions = snoc(ast->expressions, expr, _M_pool);
3832 ADVANCE(']', "]");
3835 UPDATE_POS(ast, start, token_stream.cursor());
3836 node = ast;
3838 return true;
3841 bool Parser::parseNewInitializer(NewInitializerAST *&node)
3843 std::size_t start = token_stream.cursor();
3845 CHECK('(');
3847 NewInitializerAST *ast = CreateNode<NewInitializerAST>(_M_pool);
3849 parseCommaExpression(ast->expression);
3851 CHECK(')');
3853 UPDATE_POS(ast, start, token_stream.cursor());
3854 node = ast;
3856 return true;
3859 bool Parser::parseDeleteExpression(ExpressionAST *&node)
3861 std::size_t start = token_stream.cursor();
3863 DeleteExpressionAST *ast = CreateNode<DeleteExpressionAST>(_M_pool);
3865 if (token_stream.lookAhead() == Token_scope
3866 && token_stream.lookAhead(1) == Token_delete)
3868 ast->scope_token = token_stream.cursor();
3869 token_stream.nextToken();
3872 CHECK(Token_delete);
3873 ast->delete_token = token_stream.cursor() - 1;
3875 if (token_stream.lookAhead() == '[')
3877 ast->lbracket_token = token_stream.cursor();
3878 token_stream.nextToken();
3879 CHECK(']');
3880 ast->rbracket_token = token_stream.cursor() - 1;
3883 if (!parseCastExpression(ast->expression))
3884 return false;
3886 UPDATE_POS(ast, start, token_stream.cursor());
3887 node = ast;
3889 return true;
3892 bool Parser::parseCastExpression(ExpressionAST *&node)
3894 std::size_t start = token_stream.cursor();
3896 if (token_stream.lookAhead() == '(')
3898 token_stream.nextToken();
3900 CastExpressionAST *ast = CreateNode<CastExpressionAST>(_M_pool);
3902 if (parseTypeId(ast->type_id))
3904 if (token_stream.lookAhead() == ')')
3906 token_stream.nextToken();
3908 if (parseCastExpression(ast->expression))
3910 UPDATE_POS(ast, start, token_stream.cursor());
3911 node = ast;
3913 return true;
3919 token_stream.rewind((int) start);
3920 return parseUnaryExpression(node);
3923 bool Parser::parsePmExpression(ExpressionAST *&node)
3925 std::size_t start = token_stream.cursor();
3927 if (!parseCastExpression(node) || !node) // ### fixme
3928 return false;
3930 while (token_stream.lookAhead() == Token_ptrmem)
3932 std::size_t op = token_stream.cursor();
3933 token_stream.nextToken();
3935 ExpressionAST *rightExpr = 0;
3936 if (!parseCastExpression(rightExpr))
3937 return false;
3939 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
3940 ast->op = op;
3941 ast->left_expression = node;
3942 ast->right_expression = rightExpr;
3944 UPDATE_POS(ast, start, token_stream.cursor());
3945 node = ast;
3948 return true;
3951 bool Parser::parseMultiplicativeExpression(ExpressionAST *&node)
3953 std::size_t start = token_stream.cursor();
3955 if (!parsePmExpression(node))
3956 return false;
3958 while (token_stream.lookAhead() == '*'
3959 || token_stream.lookAhead() == '/'
3960 || token_stream.lookAhead() == '%')
3962 std::size_t op = token_stream.cursor();
3963 token_stream.nextToken();
3965 ExpressionAST *rightExpr = 0;
3966 if (!parsePmExpression(rightExpr))
3967 return false;
3969 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
3970 ast->op = op;
3971 ast->left_expression = node;
3972 ast->right_expression = rightExpr;
3974 UPDATE_POS(ast, start, token_stream.cursor());
3975 node = ast;
3978 return true;
3982 bool Parser::parseAdditiveExpression(ExpressionAST *&node)
3984 std::size_t start = token_stream.cursor();
3986 if (!parseMultiplicativeExpression(node))
3987 return false;
3989 while (token_stream.lookAhead() == '+' || token_stream.lookAhead() == '-')
3991 std::size_t op = token_stream.cursor();
3992 token_stream.nextToken();
3994 ExpressionAST *rightExpr = 0;
3995 if (!parseMultiplicativeExpression(rightExpr))
3996 return false;
3998 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
3999 ast->op = op;
4000 ast->left_expression = node;
4001 ast->right_expression = rightExpr;
4003 UPDATE_POS(ast, start, token_stream.cursor());
4004 node = ast;
4007 return true;
4010 bool Parser::parseShiftExpression(ExpressionAST *&node)
4012 std::size_t start = token_stream.cursor();
4014 if (!parseAdditiveExpression(node))
4015 return false;
4017 while (token_stream.lookAhead() == Token_shift)
4019 std::size_t op = token_stream.cursor();
4020 token_stream.nextToken();
4022 ExpressionAST *rightExpr = 0;
4023 if (!parseAdditiveExpression(rightExpr))
4024 return false;
4026 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4027 ast->op = op;
4028 ast->left_expression = node;
4029 ast->right_expression = rightExpr;
4031 UPDATE_POS(ast, start, token_stream.cursor());
4032 node = ast;
4035 return true;
4038 bool Parser::parseRelationalExpression(ExpressionAST *&node, bool templArgs)
4040 std::size_t start = token_stream.cursor();
4042 if (!parseShiftExpression(node))
4043 return false;
4045 while (token_stream.lookAhead() == '<'
4046 || (token_stream.lookAhead() == '>' && !templArgs)
4047 || token_stream.lookAhead() == Token_leq
4048 || token_stream.lookAhead() == Token_geq)
4050 std::size_t op = token_stream.cursor();
4051 token_stream.nextToken();
4053 ExpressionAST *rightExpr = 0;
4054 if (!parseShiftExpression(rightExpr))
4055 return false;
4057 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4058 ast->op = op;
4059 ast->left_expression = node;
4060 ast->right_expression = rightExpr;
4062 UPDATE_POS(ast, start, token_stream.cursor());
4063 node = ast;
4066 return true;
4069 bool Parser::parseEqualityExpression(ExpressionAST *&node, bool templArgs)
4071 std::size_t start = token_stream.cursor();
4073 if (!parseRelationalExpression(node, templArgs))
4074 return false;
4076 while (token_stream.lookAhead() == Token_eq
4077 || token_stream.lookAhead() == Token_not_eq)
4079 std::size_t op = token_stream.cursor();
4080 token_stream.nextToken();
4082 ExpressionAST *rightExpr = 0;
4083 if (!parseRelationalExpression(rightExpr, templArgs))
4084 return false;
4086 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4087 ast->op = op;
4088 ast->left_expression = node;
4089 ast->right_expression = rightExpr;
4091 UPDATE_POS(ast, start, token_stream.cursor());
4092 node = ast;
4095 return true;
4098 bool Parser::parseAndExpression(ExpressionAST *&node, bool templArgs)
4100 std::size_t start = token_stream.cursor();
4102 if (!parseEqualityExpression(node, templArgs))
4103 return false;
4105 while (token_stream.lookAhead() == '&')
4107 std::size_t op = token_stream.cursor();
4108 token_stream.nextToken();
4110 ExpressionAST *rightExpr = 0;
4111 if (!parseEqualityExpression(rightExpr, templArgs))
4112 return false;
4114 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4115 ast->op = op;
4116 ast->left_expression = node;
4117 ast->right_expression = rightExpr;
4119 UPDATE_POS(ast, start, token_stream.cursor());
4120 node = ast;
4123 return true;
4126 bool Parser::parseExclusiveOrExpression(ExpressionAST *&node, bool templArgs)
4128 std::size_t start = token_stream.cursor();
4130 if (!parseAndExpression(node, templArgs))
4131 return false;
4133 while (token_stream.lookAhead() == '^')
4135 std::size_t op = token_stream.cursor();
4136 token_stream.nextToken();
4138 ExpressionAST *rightExpr = 0;
4139 if (!parseAndExpression(rightExpr, templArgs))
4140 return false;
4142 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4143 ast->op = op;
4144 ast->left_expression = node;
4145 ast->right_expression = rightExpr;
4147 UPDATE_POS(ast, start, token_stream.cursor());
4148 node = ast;
4151 return true;
4154 bool Parser::parseInclusiveOrExpression(ExpressionAST *&node, bool templArgs)
4156 std::size_t start = token_stream.cursor();
4158 if (!parseExclusiveOrExpression(node, templArgs))
4159 return false;
4161 while (token_stream.lookAhead() == '|')
4163 std::size_t op = token_stream.cursor();
4164 token_stream.nextToken();
4166 ExpressionAST *rightExpr = 0;
4167 if (!parseExclusiveOrExpression(rightExpr, templArgs))
4168 return false;
4170 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4171 ast->op = op;
4172 ast->left_expression = node;
4173 ast->right_expression = rightExpr;
4175 UPDATE_POS(ast, start, token_stream.cursor());
4176 node = ast;
4179 return true;
4182 bool Parser::parseLogicalAndExpression(ExpressionAST *&node, bool templArgs)
4184 std::size_t start = token_stream.cursor();
4186 if (!parseInclusiveOrExpression(node, templArgs))
4187 return false;
4189 while (token_stream.lookAhead() == Token_and)
4191 std::size_t op = token_stream.cursor();
4192 token_stream.nextToken();
4194 ExpressionAST *rightExpr = 0;
4195 if (!parseInclusiveOrExpression(rightExpr, templArgs))
4196 return false;
4198 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4199 ast->op = op;
4200 ast->left_expression = node;
4201 ast->right_expression = rightExpr;
4203 UPDATE_POS(ast, start, token_stream.cursor());
4204 node = ast;
4207 return true;
4210 bool Parser::parseLogicalOrExpression(ExpressionAST *&node, bool templArgs)
4212 std::size_t start = token_stream.cursor();
4214 if (!parseLogicalAndExpression(node, templArgs))
4215 return false;
4217 while (token_stream.lookAhead() == Token_or)
4219 std::size_t op = token_stream.cursor();
4220 token_stream.nextToken();
4222 ExpressionAST *rightExpr = 0;
4223 if (!parseLogicalAndExpression(rightExpr, templArgs))
4224 return false;
4226 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4227 ast->op = op;
4228 ast->left_expression = node;
4229 ast->right_expression = rightExpr;
4231 UPDATE_POS(ast, start, token_stream.cursor());
4232 node = ast;
4235 return true;
4238 bool Parser::parseConditionalExpression(ExpressionAST *&node)
4240 std::size_t start = token_stream.cursor();
4242 if (!parseLogicalOrExpression(node))
4243 return false;
4245 if (token_stream.lookAhead() == '?')
4247 token_stream.nextToken();
4249 ExpressionAST *leftExpr = 0;
4250 if (!parseExpression(leftExpr))
4251 return false;
4253 CHECK(':');
4255 ExpressionAST *rightExpr = 0;
4256 if (!parseAssignmentExpression(rightExpr))
4257 return false;
4259 ConditionalExpressionAST *ast
4260 = CreateNode<ConditionalExpressionAST>(_M_pool);
4262 ast->condition = node;
4263 ast->left_expression = leftExpr;
4264 ast->right_expression = rightExpr;
4266 UPDATE_POS(ast, start, token_stream.cursor());
4267 node = ast;
4270 return true;
4273 bool Parser::parseAssignmentExpression(ExpressionAST *&node)
4275 std::size_t start = token_stream.cursor();
4277 if (token_stream.lookAhead() == Token_throw && !parseThrowExpression(node))
4278 return false;
4279 else if (!parseConditionalExpression(node))
4280 return false;
4282 while (token_stream.lookAhead() == Token_assign
4283 || token_stream.lookAhead() == '=')
4285 std::size_t op = token_stream.cursor();
4286 token_stream.nextToken();
4288 ExpressionAST *rightExpr = 0;
4289 if (!parseConditionalExpression(rightExpr))
4290 return false;
4292 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4293 ast->op = op;
4294 ast->left_expression = node;
4295 ast->right_expression = rightExpr;
4297 UPDATE_POS(ast, start, token_stream.cursor());
4298 node = ast;
4301 return true;
4304 bool Parser::parseConstantExpression(ExpressionAST *&node)
4306 return parseConditionalExpression(node);
4309 bool Parser::parseExpression(ExpressionAST *&node)
4311 return parseCommaExpression(node);
4314 bool Parser::parseCommaExpression(ExpressionAST *&node)
4316 std::size_t start = token_stream.cursor();
4318 if (!parseAssignmentExpression(node))
4319 return false;
4321 while (token_stream.lookAhead() == ',')
4323 std::size_t op = token_stream.cursor();
4324 token_stream.nextToken();
4326 ExpressionAST *rightExpr = 0;
4327 if (!parseAssignmentExpression(rightExpr))
4328 return false;
4330 BinaryExpressionAST *ast = CreateNode<BinaryExpressionAST>(_M_pool);
4331 ast->op = op;
4332 ast->left_expression = node;
4333 ast->right_expression = rightExpr;
4335 UPDATE_POS(ast, start, token_stream.cursor());
4336 node = ast;
4339 return true;
4342 bool Parser::parseThrowExpression(ExpressionAST *&node)
4344 std::size_t start = token_stream.cursor();
4346 CHECK(Token_throw);
4348 ThrowExpressionAST *ast = CreateNode<ThrowExpressionAST>(_M_pool);
4349 ast->throw_token = token_stream.cursor() - 1;
4351 parseAssignmentExpression(ast->expression);
4353 UPDATE_POS(ast, start, token_stream.cursor());
4354 node = ast;
4356 return true;
4359 bool Parser::parseQ_ENUMS(DeclarationAST *&node)
4361 if (token_stream.lookAhead() != Token_Q_ENUMS)
4362 return false;
4364 if (token_stream.lookAhead(1) != '(')
4365 return false;
4367 token_stream.nextToken();
4368 token_stream.nextToken();
4370 int firstToken = token_stream.cursor();
4371 while (token_stream.lookAhead() != ')') {
4372 token_stream.nextToken();
4374 QEnumsAST *ast = CreateNode<QEnumsAST>(_M_pool);
4375 UPDATE_POS(ast, firstToken, token_stream.cursor());
4376 node = ast;
4378 token_stream.nextToken();
4380 return true;
4383 bool Parser::parseQ_PROPERTY(DeclarationAST *&node)
4385 if (token_stream.lookAhead() != Token_Q_PROPERTY)
4386 return false;
4388 if (token_stream.lookAhead(1) != '(')
4389 return false;
4391 token_stream.nextToken();
4392 token_stream.nextToken();
4394 int firstToken = token_stream.cursor();
4395 while (token_stream.lookAhead() != ')') {
4396 token_stream.nextToken();
4398 QPropertyAST *ast = CreateNode<QPropertyAST>(_M_pool);
4399 UPDATE_POS(ast, firstToken, token_stream.cursor());
4400 node = ast;
4402 // const Token &t1 = token_stream[firstToken];
4403 // const Token &t2 = token_stream[token_stream.cursor()];
4404 // printf("property: %s\n",
4405 // qPrintable(QString::fromLatin1(t1.text + t1.position, t2.position - t1.position)));
4407 token_stream.nextToken();
4409 return true;
4412 bool Parser::block_errors(bool block)
4414 bool current = _M_block_errors;
4415 _M_block_errors = block;
4416 return current;
4420 // kate: space-indent on; indent-width 2; replace-tabs on;