Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: dart/frog/leg/scanner/parser.dart

Issue 8508016: Create class AST nodes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: frogsh Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « dart/frog/leg/scanner/listener.dart ('k') | dart/frog/leg/scanner/parser_bench.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * An event generating parser of Dart programs. This parser expects 6 * An event generating parser of Dart programs. This parser expects
7 * all tokens in a linked list. 7 * all tokens in a linked list.
8 */ 8 */
9 class Parser<L extends Listener> { 9 class PartialParser<L extends Listener> {
10 final L listener; 10 final L listener;
11 11
12 Parser(L this.listener); 12 // TODO(ahe): Clean up the following fields.
13 Function beginTypeArguments;
14 Function parseTypeFunction;
15 Function endTypeArguments;
16 Function handleNoTypeArguments;
17
18 // TODO(ahe): Clean up the following fields.
19 Function beginTypeVariables;
20 Function parseTypeVariableFunction;
21 Function endTypeVariables;
22 Function handleNoTypeVariables;
23
24 PartialParser(L this.listener) {
25 beginTypeArguments = listener.beginTypeArguments;
26 parseTypeFunction = parseType;
27 endTypeArguments = listener.endTypeArguments;
28 handleNoTypeArguments = listener.handleNoTypeArguments;
29
30 beginTypeVariables = listener.beginTypeVariables;
31 parseTypeVariableFunction = parseTypeVariable;
32 endTypeVariables = listener.endTypeVariables;
33 handleNoTypeVariables = listener.handleNoTypeVariables;
34
35 if (parseTypeFunction === null) {
36 // TODO(ahe): Work around bug in Frog optimizer.
37 listener.beginTypeArguments(null);
38 listener.endTypeArguments(0, null, null);
39 listener.handleNoTypeArguments(null);
40 listener.beginTypeVariables(null);
41 parseTypeVariable(null);
42 listener.endTypeVariables(0, null, null);
43 listener.handleNoTypeVariables(null);
44 }
45 }
13 46
14 // TODO(ahe): Rename this method. It is too subtle compared to token.next. 47 // TODO(ahe): Rename this method. It is too subtle compared to token.next.
15 Token next(Token token) => checkEof(token.next); 48 Token next(Token token) => checkEof(token.next);
16 49
17 Token checkEof(Token token) { 50 Token checkEof(Token token) {
18 if (token.kind === EOF_TOKEN) { 51 if (token.kind === EOF_TOKEN) {
19 listener.unexpectedEof(); 52 listener.unexpectedEof();
20 throw 'Unexpected EOF'; 53 throw 'Unexpected EOF';
21 } 54 }
22 return token; 55 return token;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 token = next(token); 195 token = next(token);
163 } while (token !== null); 196 } while (token !== null);
164 throw 'Internal error: unreachable code'; 197 throw 'Internal error: unreachable code';
165 } 198 }
166 199
167 Token parseClass(Token token) { 200 Token parseClass(Token token) {
168 Token begin = token; 201 Token begin = token;
169 listener.beginClass(token); 202 listener.beginClass(token);
170 token = parseIdentifier(next(token)); 203 token = parseIdentifier(next(token));
171 token = parseTypeVariablesOpt(token); 204 token = parseTypeVariablesOpt(token);
172 token = parseSuperclassClauseOpt(token); 205 Token extendsKeyword;
173 token = parseImplementsOpt(token); 206 if (optional('extends', token)) {
207 extendsKeyword = token;
208 token = parseType(next(token));
209 } else {
210 extendsKeyword = null;
211 listener.handleNoType(token);
212 }
213 Token implementsKeyword;
214 int interfacesCount = 0;
215 if (optional('implements', token)) {
216 do {
217 token = parseType(next(token));
218 ++interfacesCount;
219 } while (optional(',', token));
220 }
174 token = parseNativeClassClauseOpt(token); 221 token = parseNativeClassClauseOpt(token);
175 token = parseClassBody(token); 222 token = parseClassBody(token);
176 listener.endClass(begin, token); 223 listener.endClass(interfacesCount, begin, extendsKeyword, implementsKeyword,
224 token);
177 return token.next; 225 return token.next;
178 } 226 }
179 227
180 Token parseNativeClassClauseOpt(Token token) { 228 Token parseNativeClassClauseOpt(Token token) {
181 if (optional('native', token)) { 229 if (optional('native', token)) {
182 return parseString(next(token)); 230 return parseString(next(token));
183 } 231 }
184 return token; 232 return token;
185 } 233 }
186 234
187 Token parseString(Token token) { 235 Token parseString(Token token) {
188 if (token.kind === STRING_TOKEN) { 236 if (token.kind === STRING_TOKEN) {
189 return next(token); 237 return next(token);
190 } else { 238 } else {
191 return listener.expected('string', token); 239 return listener.expected('string', token);
192 } 240 }
193 } 241 }
194 242
195 Token parseIdentifier(Token token) { 243 Token parseIdentifier(Token token) {
196 if (isIdentifier(token)) { 244 if (isIdentifier(token)) {
197 listener.handleIdentifier(token); 245 listener.handleIdentifier(token);
198 } else { 246 } else {
199 listener.expectedIdentifier(token); 247 listener.expectedIdentifier(token);
200 } 248 }
201 return next(token); 249 return next(token);
202 } 250 }
203 251
204 Token parseTypeVariablesOpt(Token token) {
205 if (!optional('<', token)) {
206 listener.handleNoTypeVariables(token);
207 return token;
208 }
209 return parseTypeVariables(token);
210 }
211
212 Token parseTypeVariables(Token token) {
213 expect('<', token);
214 listener.beginTypeVariables(token);
215 do {
216 token = parseTypeVariable(next(token));
217 } while (optional(',', token));
218 listener.endTypeVariables(token);
219 return expect('>', token);
220 }
221
222 Token expect(String string, Token token) { 252 Token expect(String string, Token token) {
223 if (string !== token.stringValue) { 253 if (string !== token.stringValue) {
224 return listener.expected(string, token); 254 return listener.expected(string, token);
225 } 255 }
226 return token.next; 256 return token.next;
227 } 257 }
228 258
229 Token parseTypeVariable(Token token) { 259 Token parseTypeVariable(Token token) {
230 listener.beginTypeVariable(token); 260 listener.beginTypeVariable(token);
231 token = parseIdentifier(token); 261 token = parseIdentifier(token);
232 token = parseSuperclassClauseOpt(token); 262 if (optional('extends', token)) {
263 token = parseType(next(token));
264 } else {
265 listener.handleNoType(token);
266 }
233 listener.endTypeVariable(token); 267 listener.endTypeVariable(token);
234 return token; 268 return token;
235 } 269 }
236 270
237 bool optional(String value, Token token) => value === token.stringValue; 271 bool optional(String value, Token token) => value === token.stringValue;
238 272
239 Token parseSuperclassClauseOpt(Token token) {
240 if (optional('extends', token)) {
241 return parseType(next(token));
242 }
243 return token;
244 }
245
246 Token parseType(Token token) { 273 Token parseType(Token token) {
247 // TODO(ahe): Rename this method to parseTypeOrVar? 274 // TODO(ahe): Rename this method to parseTypeOrVar?
248 if (isIdentifier(token)) { 275 if (isIdentifier(token)) {
249 token = parseIdentifier(token); 276 token = parseIdentifier(token);
250 while (optional('.', token)) { 277 while (optional('.', token)) {
251 // TODO(ahe): Validate that there are at most two identifiers. 278 // TODO(ahe): Validate that there are at most two identifiers.
252 token = parseIdentifier(next(token)); 279 token = parseIdentifier(next(token));
253 } 280 }
254 } else if (optional('var', token)) { 281 } else if (optional('var', token)) {
255 listener.handleVarKeyword(token); 282 listener.handleVarKeyword(token);
256 listener.endType(token); 283 listener.endType(token);
257 return next(token); 284 return next(token);
258 } else { 285 } else {
259 token = listener.expectedType(token); 286 token = listener.expectedType(token);
260 } 287 }
261 token = parseTypeArgumentsOpt(token); 288 token = parseTypeArgumentsOpt(token);
262 listener.endType(token); 289 listener.endType(token);
263 return token; 290 return token;
264 } 291 }
265 292
266 Token parseTypeArgumentsOpt(Token token) { 293 Token parseTypeArgumentsOpt(Token token) {
294 return parseStuff(token, beginTypeArguments, parseTypeFunction,
295 endTypeArguments, handleNoTypeArguments);
296 }
297
298 Token parseTypeVariablesOpt(Token token) {
299 return parseStuff(token, beginTypeVariables, parseTypeVariableFunction,
300 endTypeVariables, handleNoTypeVariables);
301 }
302
303 // TODO(ahe): Clean this up.
304 Token parseStuff(Token token, Function beginStuff, Function stuffParser,
305 Function endStuff, Function handleNoStuff) {
267 if (optional('<', token)) { 306 if (optional('<', token)) {
268 listener.beginTypeArguments(next(token)); 307 Token begin = token;
308 beginStuff(begin);
309 int count = 0;
269 do { 310 do {
270 token = parseType(next(token)); 311 token = stuffParser(next(token));
312 ++count;
271 } while (optional(',', token)); 313 } while (optional(',', token));
314 endStuff(count, begin, token);
272 return expect('>', token); 315 return expect('>', token);
273 } 316 }
317 handleNoStuff(token);
274 return token; 318 return token;
275 } 319 }
276 320
277 Token parseImplementsOpt(Token token) {
278 if (optional('implements', token)) {
279 do {
280 token = parseType(next(token));
281 } while (optional(',', token));
282 }
283 return token;
284 }
285
286 Token parseClassBody(Token token) => skipBlock(token); 321 Token parseClassBody(Token token) => skipBlock(token);
287 322
288 Token parseTopLevelMember(Token token) { 323 Token parseTopLevelMember(Token token) {
289 Token start = token; 324 Token start = token;
290 listener.beginTopLevelMember(token); 325 listener.beginTopLevelMember(token);
291 Token previous = token; 326 Token previous = token;
292 LOOP: while (token !== null) { 327 LOOP: while (token !== null) {
293 final kind = token.kind; 328 final kind = token.kind;
294 switch (true) { 329 switch (true) {
295 case kind === LBRACE_TOKEN: 330 case kind === LBRACE_TOKEN:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 while (token !== null && 376 while (token !== null &&
342 token.kind !== LPAREN_TOKEN && 377 token.kind !== LPAREN_TOKEN &&
343 token.kind !== RPAREN_TOKEN) { 378 token.kind !== RPAREN_TOKEN) {
344 token = next(token); 379 token = next(token);
345 } 380 }
346 token = expect(')', token); 381 token = expect(')', token);
347 return expect(';', token); 382 return expect(';', token);
348 } 383 }
349 } 384 }
350 385
351 class BodyParser extends Parser/* <BodyListener> Frog bug #320 */ { 386 class Parser extends PartialParser/* <NodeListener> Frog bug #320 */ {
352 BodyParser(BodyListener listener) : super(listener); 387 Parser(NodeListener listener) : super(listener);
353 388
354 Token parseFunction(Token token) { 389 Token parseFunction(Token token) {
355 listener.beginFunction(token); 390 listener.beginFunction(token);
356 token = parseReturnTypeOpt(token); 391 token = parseReturnTypeOpt(token);
357 listener.beginFunctionName(token); 392 listener.beginFunctionName(token);
358 token = parseIdentifier(token); 393 token = parseIdentifier(token);
359 listener.endFunctionName(token); 394 listener.endFunctionName(token);
360 token = parseFormalParameters(token); 395 token = parseFormalParameters(token);
361 return parseFunctionBody(token); 396 return parseFunctionBody(token);
362 } 397 }
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 if (optional(';', token)) { 745 if (optional(';', token)) {
711 listener.endRethrowStatement(throwToken, token); 746 listener.endRethrowStatement(throwToken, token);
712 return token.next; 747 return token.next;
713 } else { 748 } else {
714 token = parseExpression(token); 749 token = parseExpression(token);
715 listener.endThrowStatement(throwToken, token); 750 listener.endThrowStatement(throwToken, token);
716 return expectSemicolon(token); 751 return expectSemicolon(token);
717 } 752 }
718 } 753 }
719 } 754 }
OLDNEW
« no previous file with comments | « dart/frog/leg/scanner/listener.dart ('k') | dart/frog/leg/scanner/parser_bench.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698