annotate generator/parser/parser.cpp @ 414:b2a803c73b89 default tip

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