annotate generator/parser/parser.cpp @ 1:e78566595089

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