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

Side by Side Diff: frog/parser.dart

Issue 8952006: Fix factories in Frog to correspond to the new syntax. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years 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
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 // TODO(jimhug): Error recovery needs major work! 5 // TODO(jimhug): Error recovery needs major work!
6 /** 6 /**
7 * A simple recursive descent parser for the dart language. 7 * A simple recursive descent parser for the dart language.
8 * 8 *
9 * This parser is designed to be more permissive than the official 9 * This parser is designed to be more permissive than the official
10 * Dart grammar. It is expected that many grammar errors would be 10 * Dart grammar. It is expected that many grammar errors would be
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 if (_maybeEat(TokenKind.IMPLEMENTS)) { 268 if (_maybeEat(TokenKind.IMPLEMENTS)) {
269 _implements = typeList(); 269 _implements = typeList();
270 } 270 }
271 271
272 var _native = null; 272 var _native = null;
273 if (_maybeEat(TokenKind.NATIVE)) { 273 if (_maybeEat(TokenKind.NATIVE)) {
274 _native = maybeStringLiteral(); 274 _native = maybeStringLiteral();
275 if (_native != null) _native = new NativeType(_native); 275 if (_native != null) _native = new NativeType(_native);
276 } 276 }
277 277
278 var _factory = null; 278 bool oldFactory = _maybeEat(TokenKind.FACTORY);
279 if (_maybeEat(TokenKind.FACTORY)) { 279 var defaultType = null;
280 // Note: this can't be type(), because for some strange reason these are 280 if (oldFactory || _maybeEat(TokenKind.DEFAULT)) {
281 // type parameters, not type arguments. 281 // TODO(jmesserly): keep old factory support for now. Remove soon.
282 _factory = nameTypeReference(); 282 if (oldFactory) {
283 world.warning('factory no longer supported, use "default" instead',
sra1 2011/12/15 02:38:17 I think Frog warnings need to be consistent with q
jimhug 2011/12/15 17:05:04 SGTM. I just checked and both Python and JS use s
Jennifer Messerly 2011/12/15 19:28:18 +1 on consistency. I'm trying to be consistent wit
284 _previousToken.span);
285 }
286
287 // Note: this can't be type() because it has type parameters not type
288 // arguments.
289 var baseType = nameTypeReference();
290 var typeParams = null;
283 if (_peekKind(TokenKind.LT)) { 291 if (_peekKind(TokenKind.LT)) {
284 // TODO(jmesserly): not sure what to do with these. They aren't used for 292 typeParams = typeParameters();
285 // anything as far as I can tell.
286 typeParameters();
287 } 293 }
294 defaultType = new DefaultTypeReference(oldFactory,
295 baseType, typeParams, _makeSpan(baseType.span.start));
288 } 296 }
289 297
290 var body = []; 298 var body = [];
291 if (_maybeEat(TokenKind.LBRACE)) { 299 if (_maybeEat(TokenKind.LBRACE)) {
292 while (!_maybeEat(TokenKind.RBRACE)) { 300 while (!_maybeEat(TokenKind.RBRACE)) {
293 body.add(declaration()); 301 body.add(declaration());
294 if (_recover) { 302 if (_recover) {
295 if (!_recoverTo(TokenKind.RBRACE, TokenKind.SEMICOLON)) break; 303 if (!_recoverTo(TokenKind.RBRACE, TokenKind.SEMICOLON)) break;
296 _maybeEat(TokenKind.SEMICOLON); 304 _maybeEat(TokenKind.SEMICOLON);
297 } 305 }
298 } 306 }
299 } else { 307 } else {
300 _errorExpected('block starting with "{" or ";"'); 308 _errorExpected('block starting with "{" or ";"');
301 } 309 }
302 return new TypeDefinition(kind == TokenKind.CLASS, name, typeParams, 310 return new TypeDefinition(kind == TokenKind.CLASS, name, typeParams,
303 _extends, _implements, _native, _factory, body, _makeSpan(start)); 311 _extends, _implements, _native, defaultType, body, _makeSpan(start));
304 } 312 }
305 313
306 functionTypeAlias() { 314 functionTypeAlias() {
307 int start = _peekToken.start; 315 int start = _peekToken.start;
308 _eat(TokenKind.TYPEDEF); 316 _eat(TokenKind.TYPEDEF);
309 317
310 var di = declaredIdentifier(false); 318 var di = declaredIdentifier(false);
311 var typeParams = null; 319 var typeParams = null;
312 if (_peekKind(TokenKind.LT)) { 320 if (_peekKind(TokenKind.LT)) {
313 typeParams = typeParameters(); 321 typeParams = typeParameters();
314 } 322 }
315 var formals = formalParameterList(); 323 var formals = formalParameterList();
316 _eatSemicolon(); 324 _eatSemicolon();
317 325
318 var func = new FunctionDefinition(null, di.type, di.name, formals, 326 var func = new FunctionDefinition(null, di.type, di.name, formals,
319 null, null, null, null, _makeSpan(start)); 327 null, null, null, _makeSpan(start));
320 328
321 return new FunctionTypeDefinition(func, typeParams, _makeSpan(start)); 329 return new FunctionTypeDefinition(func, typeParams, _makeSpan(start));
322 } 330 }
323 331
324 initializers() { 332 initializers() {
325 _inhibitLambda = true; 333 _inhibitLambda = true;
326 var ret = []; 334 var ret = [];
327 do { 335 do {
328 ret.add(expression()); 336 ret.add(expression());
329 } while (_maybeEat(TokenKind.COMMA)); 337 } while (_maybeEat(TokenKind.COMMA));
(...skipping 18 matching lines...) Expand all
348 } 356 }
349 } else if (!inExpression) { 357 } else if (!inExpression) {
350 if (_maybeEat(TokenKind.SEMICOLON)) { 358 if (_maybeEat(TokenKind.SEMICOLON)) {
351 return null; 359 return null;
352 } 360 }
353 } 361 }
354 362
355 _error('Expected function body (neither { nor => found)'); 363 _error('Expected function body (neither { nor => found)');
356 } 364 }
357 365
358 finishField(start, modifiers, typeParams, type, name, value) { 366 finishField(start, modifiers, type, name, value) {
359 if (typeParams != null) {
360 world.internalError('trying to create a generic field',
361 _makeSpan(start));
362 }
363 var names = [name]; 367 var names = [name];
364 var values = [value]; 368 var values = [value];
365 369
366 while (_maybeEat(TokenKind.COMMA)) { 370 while (_maybeEat(TokenKind.COMMA)) {
367 names.add(identifier()); 371 names.add(identifier());
368 if (_maybeEat(TokenKind.ASSIGN)) { 372 if (_maybeEat(TokenKind.ASSIGN)) {
369 values.add(expression()); 373 values.add(expression());
370 } else { 374 } else {
371 values.add(null); 375 values.add(null);
372 } 376 }
373 } 377 }
374 378
375 _eatSemicolon(); 379 _eatSemicolon();
376 return new VariableDefinition(modifiers, type, names, values, 380 return new VariableDefinition(modifiers, type, names, values,
377 _makeSpan(start)); 381 _makeSpan(start));
378 } 382 }
379 383
380 finishDefinition(int start, List<Token> modifiers, di, 384 finishDefinition(int start, List<Token> modifiers, di) {
381 List<ParameterType> typeParams) {
382 switch(_peek()) { 385 switch(_peek()) {
383 case TokenKind.LPAREN: 386 case TokenKind.LPAREN:
384 var formals = formalParameterList(); 387 var formals = formalParameterList();
385 var inits = null, native = null; 388 var inits = null, native = null;
386 if (_maybeEat(TokenKind.COLON)) { 389 if (_maybeEat(TokenKind.COLON)) {
387 inits = initializers(); 390 inits = initializers();
388 } 391 }
389 if (_maybeEat(TokenKind.NATIVE)) { 392 if (_maybeEat(TokenKind.NATIVE)) {
390 native = maybeStringLiteral(); 393 native = maybeStringLiteral();
391 if (native == null) native = ''; 394 if (native == null) native = '';
392 } 395 }
393 var body = functionBody(/*inExpression:*/false); 396 var body = functionBody(/*inExpression:*/false);
394 if (di.name == null) { 397 if (di.name == null) {
395 // TODO(jimhug): Must be named constructor - verify how? 398 // TODO(jimhug): Must be named constructor - verify how?
396 di.name = di.type.name; 399 di.name = di.type.name;
397 } 400 }
398 return new FunctionDefinition(modifiers, di.type, di.name, formals, 401 return new FunctionDefinition(modifiers, di.type, di.name, formals,
399 typeParams, inits, native, body, _makeSpan(start)); 402 inits, native, body, _makeSpan(start));
400 403
401 case TokenKind.ASSIGN: 404 case TokenKind.ASSIGN:
402 _eat(TokenKind.ASSIGN); 405 _eat(TokenKind.ASSIGN);
403 var value = expression(); 406 var value = expression();
404 return finishField(start, modifiers, typeParams, di.type, di.name, value ); 407 return finishField(start, modifiers, di.type, di.name, value);
405 408
406 case TokenKind.COMMA: 409 case TokenKind.COMMA:
407 case TokenKind.SEMICOLON: 410 case TokenKind.SEMICOLON:
408 return finishField(start, modifiers, typeParams, di.type, di.name, null) ; 411 return finishField(start, modifiers, di.type, di.name, null);
409 412
410 default: 413 default:
411 // TODO(jimhug): This error message sucks. 414 // TODO(jimhug): This error message sucks.
412 _errorExpected('declaration'); 415 _errorExpected('declaration');
413 416
414 return null; 417 return null;
415 } 418 }
416 } 419 }
417 420
418 declaration([bool includeOperators=true]) { 421 declaration([bool includeOperators=true]) {
419 int start = _peekToken.start; 422 int start = _peekToken.start;
420 if (_peekKind(TokenKind.FACTORY)) { 423 if (_peekKind(TokenKind.FACTORY)) {
421 return factoryConstructorDeclaration(); 424 return factoryConstructorDeclaration();
422 } 425 }
423 426
424 var modifiers = _readModifiers(); 427 var modifiers = _readModifiers();
425 return finishDefinition(start, modifiers, 428 return finishDefinition(start, modifiers,
426 declaredIdentifier(includeOperators), null); 429 declaredIdentifier(includeOperators));
427 } 430 }
428 431
432 // TODO(jmesserly): do we still need this method?
433 // I left it here for now to support old-style factories
jimhug 2011/12/15 17:05:04 I think we need this "forever" as we still have fa
Jennifer Messerly 2011/12/15 19:28:18 Ah, I might be misremembering the history of the c
429 factoryConstructorDeclaration() { 434 factoryConstructorDeclaration() {
430 int start = _peekToken.start; 435 int start = _peekToken.start;
431 var factoryToken = _next(); 436 var factoryToken = _next();
432 437
433 var names = [identifier()]; 438 var names = [identifier()];
434 while (_maybeEat(TokenKind.DOT)) { 439 while (_maybeEat(TokenKind.DOT)) {
435 names.add(identifier()); 440 names.add(identifier());
436 } 441 }
437 var typeParams = null;
438 if (_peekKind(TokenKind.LT)) { 442 if (_peekKind(TokenKind.LT)) {
439 typeParams = typeParameters(); 443 var tp = typeParameters();
444 world.warning('type parameters on factories are no longer supported, '
445 + 'place them on the class instead', _makeSpan(tp[0].span.start));
440 } 446 }
441 447
442 var name = null; 448 var name = null;
443 var type = null; 449 var type = null;
444 if (_maybeEat(TokenKind.DOT)) { 450 if (_maybeEat(TokenKind.DOT)) {
445 name = identifier(); 451 name = identifier();
446 } else if (typeParams == null) { 452 } else {
447 if (names.length > 1) { 453 if (names.length > 1) {
448 name = names.removeLast(); 454 name = names.removeLast();
449 } else { 455 } else {
450 name = new Identifier('', names[0].span); 456 name = new Identifier('', names[0].span);
451 } 457 }
452 } else {
453 name = new Identifier('', names[0].span);
454 } 458 }
455 459
456 if (names.length > 1) { 460 if (names.length > 1) {
457 // TODO(jimhug): This is nasty to support and currently unused. 461 // TODO(jimhug): This is nasty to support and currently unused.
458 _error('unsupported qualified name for factory', names[0].span); 462 _error('unsupported qualified name for factory', names[0].span);
459 } 463 }
460 type = new NameTypeReference(false, names[0], null, names[0].span); 464 type = new NameTypeReference(false, names[0], null, names[0].span);
461 var di = new DeclaredIdentifier(type, name, _makeSpan(start)); 465 var di = new DeclaredIdentifier(type, name, _makeSpan(start));
462 return finishDefinition(start, [factoryToken], di, typeParams); 466 return finishDefinition(start, [factoryToken], di);
463 } 467 }
464 468
465 /////////////////////////////////////////////////////////////////// 469 ///////////////////////////////////////////////////////////////////
466 // Statement productions 470 // Statement productions
467 /////////////////////////////////////////////////////////////////// 471 ///////////////////////////////////////////////////////////////////
468 Statement statement() { 472 Statement statement() {
469 switch (_peek()) { 473 switch (_peek()) {
470 case TokenKind.BREAK: 474 case TokenKind.BREAK:
471 return breakStatement(); 475 return breakStatement();
472 case TokenKind.CONTINUE: 476 case TokenKind.CONTINUE:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 if (expr.func.body is! BlockStatement) { 526 if (expr.func.body is! BlockStatement) {
523 _eatSemicolon(); 527 _eatSemicolon();
524 expr.func.span = _makeSpan(start); 528 expr.func.span = _makeSpan(start);
525 } 529 }
526 return expr.func; 530 return expr.func;
527 } else if (expr is DeclaredIdentifier) { 531 } else if (expr is DeclaredIdentifier) {
528 var value = null; 532 var value = null;
529 if (_maybeEat(TokenKind.ASSIGN)) { 533 if (_maybeEat(TokenKind.ASSIGN)) {
530 value = expression(); 534 value = expression();
531 } 535 }
532 return finishField(start, null, null, expr.type, expr.name, value); 536 return finishField(start, null, expr.type, expr.name, value);
533 } else if (_isBin(expr, TokenKind.ASSIGN) && 537 } else if (_isBin(expr, TokenKind.ASSIGN) &&
534 (expr.x is DeclaredIdentifier)) { 538 (expr.x is DeclaredIdentifier)) {
535 DeclaredIdentifier di = expr.x; // TODO(jimhug): inference should handle! 539 DeclaredIdentifier di = expr.x; // TODO(jimhug): inference should handle!
536 return finishField(start, null, null, di.type, di.name, expr.y); 540 return finishField(start, null, di.type, di.name, expr.y);
537 } else if (_isBin(expr, TokenKind.LT) && _maybeEat(TokenKind.COMMA)) { 541 } else if (_isBin(expr, TokenKind.LT) && _maybeEat(TokenKind.COMMA)) {
538 var baseType = _makeType(expr.x); 542 var baseType = _makeType(expr.x);
539 var typeArgs = [_makeType(expr.y)]; 543 var typeArgs = [_makeType(expr.y)];
540 var gt = _finishTypeArguments(baseType, 0, typeArgs); 544 var gt = _finishTypeArguments(baseType, 0, typeArgs);
541 var name = identifier(); 545 var name = identifier();
542 var value = null; 546 var value = null;
543 if (_maybeEat(TokenKind.ASSIGN)) { 547 if (_maybeEat(TokenKind.ASSIGN)) {
544 value = expression(); 548 value = expression();
545 } 549 }
546 return finishField(expr.span.start, null, null, gt, name, value); 550 return finishField(expr.span.start, null, gt, name, value);
547 } else { 551 } else {
548 _eatSemicolon(); 552 _eatSemicolon();
549 return new ExpressionStatement(expr, _makeSpan(expr.span.start)); 553 return new ExpressionStatement(expr, _makeSpan(expr.span.start));
550 } 554 }
551 } 555 }
552 556
553 Expression testCondition() { 557 Expression testCondition() {
554 _eatLeftParen(); 558 _eatLeftParen();
555 var ret = expression(); 559 var ret = expression();
556 _eat(TokenKind.RPAREN); 560 _eat(TokenKind.RPAREN);
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 } 1219 }
1216 return null; 1220 return null;
1217 } 1221 }
1218 1222
1219 _parenOrLambda() { 1223 _parenOrLambda() {
1220 int start = _peekToken.start; 1224 int start = _peekToken.start;
1221 if (_atClosureParameters()) { 1225 if (_atClosureParameters()) {
1222 var formals = formalParameterList(); 1226 var formals = formalParameterList();
1223 var body = functionBody(true); 1227 var body = functionBody(true);
1224 var func = new FunctionDefinition(null, null, null, formals, null, null, 1228 var func = new FunctionDefinition(null, null, null, formals, null, null,
1225 null, body, _makeSpan(start)); 1229 body, _makeSpan(start));
1226 return new LambdaExpression(func, func.span); 1230 return new LambdaExpression(func, func.span);
1227 } else { 1231 } else {
1228 _eatLeftParen(); 1232 _eatLeftParen();
1229 var saved = _inhibitLambda; 1233 var saved = _inhibitLambda;
1230 _inhibitLambda = false; 1234 _inhibitLambda = false;
1231 var expr = expression(); 1235 var expr = expression();
1232 _eat(TokenKind.RPAREN); 1236 _eat(TokenKind.RPAREN);
1233 _inhibitLambda = saved; 1237 _inhibitLambda = saved;
1234 return new ParenExpression(expr, _makeSpan(start)); 1238 return new ParenExpression(expr, _makeSpan(start));
1235 } 1239 }
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 1643
1640 var value = null; 1644 var value = null;
1641 if (_maybeEat(TokenKind.ASSIGN)) { 1645 if (_maybeEat(TokenKind.ASSIGN)) {
1642 if (!inOptionalBlock) { 1646 if (!inOptionalBlock) {
1643 _error('default values only allowed inside [optional] section'); 1647 _error('default values only allowed inside [optional] section');
1644 } 1648 }
1645 value = expression(); 1649 value = expression();
1646 } else if (_peekKind(TokenKind.LPAREN)) { 1650 } else if (_peekKind(TokenKind.LPAREN)) {
1647 var formals = formalParameterList(); 1651 var formals = formalParameterList();
1648 var func = new FunctionDefinition(null, type, name, formals, 1652 var func = new FunctionDefinition(null, type, name, formals,
1649 null, null, null, null, _makeSpan(start)); 1653 null, null, null, _makeSpan(start));
1650 type = new FunctionTypeReference(false, func, func.span); 1654 type = new FunctionTypeReference(false, func, func.span);
1651 } 1655 }
1652 if (inOptionalBlock && value == null) { 1656 if (inOptionalBlock && value == null) {
1653 value = new NullExpression(_makeSpan(start)); 1657 value = new NullExpression(_makeSpan(start));
1654 } 1658 }
1655 1659
1656 return new FormalNode(isThis, isRest, type, name, value, _makeSpan(start)); 1660 return new FormalNode(isThis, isRest, type, name, value, _makeSpan(start));
1657 } 1661 }
1658 1662
1659 formalParameterList() { 1663 formalParameterList() {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 name = expr.name; 1710 name = expr.name;
1707 type = null; 1711 type = null;
1708 } else if (expr is DeclaredIdentifier) { 1712 } else if (expr is DeclaredIdentifier) {
1709 name = expr.name; 1713 name = expr.name;
1710 type = expr.type; 1714 type = expr.type;
1711 } else { 1715 } else {
1712 _error('bad function body', expr.span); 1716 _error('bad function body', expr.span);
1713 } 1717 }
1714 var span = new SourceSpan(expr.span.file, expr.span.start, body.span.end); 1718 var span = new SourceSpan(expr.span.file, expr.span.start, body.span.end);
1715 var func = new FunctionDefinition(null, type, name, formals, null, null, 1719 var func = new FunctionDefinition(null, type, name, formals, null, null,
1716 null, body, span); 1720 body, span);
1717 return new LambdaExpression(func, func.span); 1721 return new LambdaExpression(func, func.span);
1718 } 1722 }
1719 1723
1720 /** Converts an expression to a [DeclaredIdentifier]. */ 1724 /** Converts an expression to a [DeclaredIdentifier]. */
1721 _makeDeclaredIdentifier(e) { 1725 _makeDeclaredIdentifier(e) {
1722 if (e is VarExpression) { 1726 if (e is VarExpression) {
1723 return new DeclaredIdentifier(null, e.name, e.span); 1727 return new DeclaredIdentifier(null, e.name, e.span);
1724 } else if (e is DeclaredIdentifier) { 1728 } else if (e is DeclaredIdentifier) {
1725 return e; 1729 return e;
1726 } else { 1730 } else {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 int _pos = 0; 1769 int _pos = 0;
1766 next() { 1770 next() {
1767 var token = tokens[_pos]; 1771 var token = tokens[_pos];
1768 ++_pos; 1772 ++_pos;
1769 if (_pos == tokens.length) { 1773 if (_pos == tokens.length) {
1770 parser.tokenizer = previousTokenizer; 1774 parser.tokenizer = previousTokenizer;
1771 } 1775 }
1772 return token; 1776 return token;
1773 } 1777 }
1774 } 1778 }
OLDNEW
« no previous file with comments | « frog/minfrog ('k') | frog/scripts/tree_gen.py » ('j') | frog/scripts/tree_gen.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698