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

Side by Side Diff: frog/parser.dart

Issue 8681027: Fix bug 578 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: prereviewed 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 | « frog/member.dart ('k') | frog/presubmit.py » ('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 // 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 260
261 var di = declaredIdentifier(false); 261 var di = declaredIdentifier(false);
262 var typeParams = null; 262 var typeParams = null;
263 if (_peekKind(TokenKind.LT)) { 263 if (_peekKind(TokenKind.LT)) {
264 typeParams = typeParameters(); 264 typeParams = typeParameters();
265 } 265 }
266 var formals = formalParameterList(); 266 var formals = formalParameterList();
267 _eatSemicolon(); 267 _eatSemicolon();
268 268
269 var func = new FunctionDefinition(null, di.type, di.name, formals, 269 var func = new FunctionDefinition(null, di.type, di.name, formals,
270 null, null, _makeSpan(start)); 270 null, null, null, _makeSpan(start));
271 271
272 return new FunctionTypeDefinition(func, typeParams, _makeSpan(start)); 272 return new FunctionTypeDefinition(func, typeParams, _makeSpan(start));
273 } 273 }
274 274
275 initializers() { 275 initializers() {
276 _inInitializers = true; 276 _inInitializers = true;
277 var ret = []; 277 var ret = [];
278 do { 278 do {
279 ret.add(expression()); 279 ret.add(expression());
280 } while (_maybeEat(TokenKind.COMMA)); 280 } while (_maybeEat(TokenKind.COMMA));
(...skipping 28 matching lines...) Expand all
309 // TODO(jimhug): This is just to get isolate.dart to parse - while 309 // TODO(jimhug): This is just to get isolate.dart to parse - while
310 // we figure out what's really going on in there. 310 // we figure out what's really going on in there.
311 return functionBody(inExpression); 311 return functionBody(inExpression);
312 } 312 }
313 } 313 }
314 } 314 }
315 315
316 _error('Expected function body (neither { nor => found)'); 316 _error('Expected function body (neither { nor => found)');
317 } 317 }
318 318
319 finishField(start, modifiers, type, name, value) { 319 finishField(start, modifiers, typeParams, type, name, value) {
320 if (typeParams !== null) {
321 world.internalError('trying to create a generic field',
322 _makeSpan(start));
323 }
320 var names = [name]; 324 var names = [name];
321 var values = [value]; 325 var values = [value];
322 326
323 while (_maybeEat(TokenKind.COMMA)) { 327 while (_maybeEat(TokenKind.COMMA)) {
324 names.add(identifier()); 328 names.add(identifier());
325 if (_maybeEat(TokenKind.ASSIGN)) { 329 if (_maybeEat(TokenKind.ASSIGN)) {
326 values.add(expression()); 330 values.add(expression());
327 } else { 331 } else {
328 values.add(null); 332 values.add(null);
329 } 333 }
330 } 334 }
331 335
332 _eatSemicolon(); 336 _eatSemicolon();
333 return new VariableDefinition(modifiers, type, names, values, 337 return new VariableDefinition(modifiers, type, names, values,
334 _makeSpan(start)); 338 _makeSpan(start));
335 } 339 }
336 340
337 finishDefinition(start, modifiers, di) { 341 finishDefinition(int start, List<Token> modifiers, di,
342 List<ParameterType> typeParams) {
338 switch(_peek()) { 343 switch(_peek()) {
339 case TokenKind.LPAREN: 344 case TokenKind.LPAREN:
340 var formals = formalParameterList(); 345 var formals = formalParameterList();
341 var inits = null; 346 var inits = null;
342 if (_maybeEat(TokenKind.COLON)) { 347 if (_maybeEat(TokenKind.COLON)) {
343 inits = initializers(); 348 inits = initializers();
344 } 349 }
345 var body = functionBody(/*inExpression:*/false); 350 var body = functionBody(/*inExpression:*/false);
346 if (di.name == null) { 351 if (di.name == null) {
347 // TODO(jimhug): Must be named constructor - verify how? 352 // TODO(jimhug): Must be named constructor - verify how?
348 di.name = di.type.name; 353 di.name = di.type.name;
349 } 354 }
350 return new FunctionDefinition(modifiers, di.type, di.name, formals, 355 return new FunctionDefinition(modifiers, di.type, di.name, formals,
351 inits, body, _makeSpan(start)); 356 typeParams, inits, body, _makeSpan(start));
352 357
353 case TokenKind.ASSIGN: 358 case TokenKind.ASSIGN:
354 _eat(TokenKind.ASSIGN); 359 _eat(TokenKind.ASSIGN);
355 var value = expression(); 360 var value = expression();
356 return finishField(start, modifiers, di.type, di.name, value); 361 return finishField(start, modifiers, typeParams, di.type, di.name, value );
357 362
358 case TokenKind.COMMA: 363 case TokenKind.COMMA:
359 case TokenKind.SEMICOLON: 364 case TokenKind.SEMICOLON:
360 return finishField(start, modifiers, di.type, di.name, null); 365 return finishField(start, modifiers, typeParams, di.type, di.name, null) ;
361 366
362 default: 367 default:
363 // TODO(jimhug): This error message sucks. 368 // TODO(jimhug): This error message sucks.
364 _errorExpected('declaration'); 369 _errorExpected('declaration');
365 370
366 return null; 371 return null;
367 } 372 }
368 } 373 }
369 374
370 declaration([bool includeOperators=true]) { 375 declaration([bool includeOperators=true]) {
371 int start = _peekToken.start; 376 int start = _peekToken.start;
372 if (_peekKind(TokenKind.FACTORY)) { 377 if (_peekKind(TokenKind.FACTORY)) {
373 return factoryConstructorDeclaration(); 378 return factoryConstructorDeclaration();
374 } 379 }
375 380
376 var modifiers = _readModifiers(); 381 var modifiers = _readModifiers();
377 return finishDefinition(start, modifiers, 382 return finishDefinition(start, modifiers,
378 declaredIdentifier(includeOperators)); 383 declaredIdentifier(includeOperators), null);
379 } 384 }
380 385
381 factoryConstructorDeclaration() { 386 factoryConstructorDeclaration() {
382 int start = _peekToken.start; 387 int start = _peekToken.start;
383 var factoryToken = _next(); 388 var factoryToken = _next();
384 389
385 var names = [identifier()]; 390 var names = [identifier()];
386 while (_maybeEat(TokenKind.DOT)) { 391 while (_maybeEat(TokenKind.DOT)) {
387 names.add(identifier()); 392 names.add(identifier());
388 } 393 }
(...skipping 15 matching lines...) Expand all
404 } else { 409 } else {
405 name = new Identifier('', names[0].span); 410 name = new Identifier('', names[0].span);
406 } 411 }
407 412
408 if (names.length > 1) { 413 if (names.length > 1) {
409 // TODO(jimhug): This is nasty to support and currently unused. 414 // TODO(jimhug): This is nasty to support and currently unused.
410 _error('unsupported qualified name for factory', names[0].span); 415 _error('unsupported qualified name for factory', names[0].span);
411 } 416 }
412 type = new NameTypeReference(false, names[0], null, names[0].span); 417 type = new NameTypeReference(false, names[0], null, names[0].span);
413 var di = new DeclaredIdentifier(type, name, _makeSpan(start)); 418 var di = new DeclaredIdentifier(type, name, _makeSpan(start));
414 return finishDefinition(start, [factoryToken], di); 419 return finishDefinition(start, [factoryToken], di, typeParams);
415 } 420 }
416 421
417 /////////////////////////////////////////////////////////////////// 422 ///////////////////////////////////////////////////////////////////
418 // Statement productions 423 // Statement productions
419 /////////////////////////////////////////////////////////////////// 424 ///////////////////////////////////////////////////////////////////
420 Statement statement() { 425 Statement statement() {
421 switch (_peek()) { 426 switch (_peek()) {
422 case TokenKind.BREAK: 427 case TokenKind.BREAK:
423 return breakStatement(); 428 return breakStatement();
424 case TokenKind.CONTINUE: 429 case TokenKind.CONTINUE:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 if (expr.func.body is! BlockStatement) { 479 if (expr.func.body is! BlockStatement) {
475 _eatSemicolon(); 480 _eatSemicolon();
476 expr.func.span = _makeSpan(start); 481 expr.func.span = _makeSpan(start);
477 } 482 }
478 return expr.func; 483 return expr.func;
479 } else if (expr is DeclaredIdentifier) { 484 } else if (expr is DeclaredIdentifier) {
480 var value = null; 485 var value = null;
481 if (_maybeEat(TokenKind.ASSIGN)) { 486 if (_maybeEat(TokenKind.ASSIGN)) {
482 value = expression(); 487 value = expression();
483 } 488 }
484 return finishField(start, null, expr.type, expr.name, value); 489 return finishField(start, null, null, expr.type, expr.name, value);
485 } else if (_isBin(expr, TokenKind.ASSIGN) && 490 } else if (_isBin(expr, TokenKind.ASSIGN) &&
486 (expr.x is DeclaredIdentifier)) { 491 (expr.x is DeclaredIdentifier)) {
487 DeclaredIdentifier di = expr.x; // TODO(jimhug): inference should handle! 492 DeclaredIdentifier di = expr.x; // TODO(jimhug): inference should handle!
488 return finishField(start, null, di.type, di.name, expr.y); 493 return finishField(start, null, null, di.type, di.name, expr.y);
489 } else if (_isBin(expr, TokenKind.LT) && _maybeEat(TokenKind.COMMA)) { 494 } else if (_isBin(expr, TokenKind.LT) && _maybeEat(TokenKind.COMMA)) {
490 var baseType = _makeType(expr.x); 495 var baseType = _makeType(expr.x);
491 var typeArgs = [_makeType(expr.y)]; 496 var typeArgs = [_makeType(expr.y)];
492 var gt = _finishTypeArguments(baseType, 0, typeArgs); 497 var gt = _finishTypeArguments(baseType, 0, typeArgs);
493 var name = identifier(); 498 var name = identifier();
494 var value = null; 499 var value = null;
495 if (_maybeEat(TokenKind.ASSIGN)) { 500 if (_maybeEat(TokenKind.ASSIGN)) {
496 value = expression(); 501 value = expression();
497 } 502 }
498 return finishField(expr.span.start, null, gt, name, value); 503 return finishField(expr.span.start, null, null, gt, name, value);
499 } else { 504 } else {
500 _eatSemicolon(); 505 _eatSemicolon();
501 return new ExpressionStatement(expr, _makeSpan(expr.span.start)); 506 return new ExpressionStatement(expr, _makeSpan(expr.span.start));
502 } 507 }
503 } 508 }
504 509
505 Expression testCondition() { 510 Expression testCondition() {
506 _eatLeftParen(); 511 _eatLeftParen();
507 var ret = expression(); 512 var ret = expression();
508 _eat(TokenKind.RPAREN); 513 _eat(TokenKind.RPAREN);
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 _errorExpected('string literal, but found incomplete string'); 1160 _errorExpected('string literal, but found incomplete string');
1156 } 1161 }
1157 return null; 1162 return null;
1158 } 1163 }
1159 1164
1160 _parenOrLambda() { 1165 _parenOrLambda() {
1161 int start = _peekToken.start; 1166 int start = _peekToken.start;
1162 if (_atClosureParameters()) { 1167 if (_atClosureParameters()) {
1163 var formals = formalParameterList(); 1168 var formals = formalParameterList();
1164 var body = functionBody(true); 1169 var body = functionBody(true);
1165 var func = new FunctionDefinition(null, null, null, formals, null, 1170 var func = new FunctionDefinition(null, null, null, formals, null, null,
1166 body, _makeSpan(start)); 1171 body, _makeSpan(start));
1167 return new LambdaExpression(func, func.span); 1172 return new LambdaExpression(func, func.span);
1168 } else { 1173 } else {
1169 var saved = _inInitializers; 1174 var saved = _inInitializers;
1170 _inInitializers = false; 1175 _inInitializers = false;
1171 var args = arguments(); 1176 var args = arguments();
1172 _inInitializers = saved; 1177 _inInitializers = saved;
1173 if (args.length == 1) { 1178 if (args.length == 1) {
1174 return new ParenExpression(args[0].value, _makeSpan(start)); 1179 return new ParenExpression(args[0].value, _makeSpan(start));
1175 } else { 1180 } else {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 modifiers.add(_next()); 1426 modifiers.add(_next());
1422 break; 1427 break;
1423 default: 1428 default:
1424 return modifiers; 1429 return modifiers;
1425 } 1430 }
1426 } 1431 }
1427 1432
1428 return null; 1433 return null;
1429 } 1434 }
1430 1435
1431 typeParameter() { 1436 ParameterType typeParameter() {
1432 // non-recursive - so always starts from zero depth 1437 // non-recursive - so always starts from zero depth
1433 int start = _peekToken.start; 1438 int start = _peekToken.start;
1434 var name = identifier(); 1439 var name = identifier();
1435 var myType = null; 1440 var myType = null;
1436 if (_maybeEat(TokenKind.EXTENDS)) { 1441 if (_maybeEat(TokenKind.EXTENDS)) {
1437 myType = type(1); 1442 myType = type(1);
1438 } 1443 }
1439 return new TypeParameter(name, myType, _makeSpan(start)); 1444
1445 var tp = new TypeParameter(name, myType, _makeSpan(start));
1446 return new ParameterType(name.name, tp);
1440 } 1447 }
1441 1448
1442 typeParameters() { 1449 List<ParameterType> typeParameters() {
1443 // always starts from zero depth 1450 // always starts from zero depth
1444 _eat(TokenKind.LT); 1451 _eat(TokenKind.LT);
1445 1452
1446 bool closed = false; 1453 bool closed = false;
1447 var ret = []; 1454 var ret = [];
1448 do { 1455 do {
1449 // inlining typeParameter to handle scope issues?
1450 var tp = typeParameter(); 1456 var tp = typeParameter();
1451 ret.add(tp); 1457 ret.add(tp);
1452 if (tp.extendsType is GenericTypeReference && tp.extendsType.depth == 0) { 1458 if (tp.typeParameter.extendsType is GenericTypeReference &&
1459 tp.typeParameter.extendsType.depth == 0) {
1453 closed = true; 1460 closed = true;
1454 break; 1461 break;
1455 } 1462 }
1456 } while (_maybeEat(TokenKind.COMMA)); 1463 } while (_maybeEat(TokenKind.COMMA));
1457 if (!closed) { 1464 if (!closed) {
1458 _eat(TokenKind.GT); 1465 _eat(TokenKind.GT);
1459 } 1466 }
1460 return ret; 1467 return ret;
1461 } 1468 }
1462 1469
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 1562
1556 var value = null; 1563 var value = null;
1557 if (_maybeEat(TokenKind.ASSIGN)) { 1564 if (_maybeEat(TokenKind.ASSIGN)) {
1558 if (!inOptionalBlock) { 1565 if (!inOptionalBlock) {
1559 _error('default values only allowed inside [optional] section'); 1566 _error('default values only allowed inside [optional] section');
1560 } 1567 }
1561 value = expression(); 1568 value = expression();
1562 } else if (_peekKind(TokenKind.LPAREN)) { 1569 } else if (_peekKind(TokenKind.LPAREN)) {
1563 var formals = formalParameterList(); 1570 var formals = formalParameterList();
1564 var func = new FunctionDefinition(null, type, name, formals, 1571 var func = new FunctionDefinition(null, type, name, formals,
1565 null, null, _makeSpan(start)); 1572 null, null, null, _makeSpan(start));
1566 type = new FunctionTypeReference(false, func, func.span); 1573 type = new FunctionTypeReference(false, func, func.span);
1567 } 1574 }
1568 if (inOptionalBlock && value == null) { 1575 if (inOptionalBlock && value == null) {
1569 value = new NullExpression(_makeSpan(start)); 1576 value = new NullExpression(_makeSpan(start));
1570 } 1577 }
1571 1578
1572 return new FormalNode(isThis, isRest, type, name, value, _makeSpan(start)); 1579 return new FormalNode(isThis, isRest, type, name, value, _makeSpan(start));
1573 } 1580 }
1574 1581
1575 formalParameterList() { 1582 formalParameterList() {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1622 name = expr.name; 1629 name = expr.name;
1623 type = null; 1630 type = null;
1624 } else if (expr is DeclaredIdentifier) { 1631 } else if (expr is DeclaredIdentifier) {
1625 name = expr.name; 1632 name = expr.name;
1626 type = expr.type; 1633 type = expr.type;
1627 } else { 1634 } else {
1628 _error('bad function body', expr.span); 1635 _error('bad function body', expr.span);
1629 } 1636 }
1630 var span = new SourceSpan(expr.span.file, expr.span.start, body.span.end); 1637 var span = new SourceSpan(expr.span.file, expr.span.start, body.span.end);
1631 var func = 1638 var func =
1632 new FunctionDefinition(null, type, name, formals, null, body, span); 1639 new FunctionDefinition(null, type, name, formals, null, null, body, span );
1633 return new LambdaExpression(func, func.span); 1640 return new LambdaExpression(func, func.span);
1634 } 1641 }
1635 1642
1636 /** Converts an expression to a [DeclaredIdentifier]. */ 1643 /** Converts an expression to a [DeclaredIdentifier]. */
1637 _makeDeclaredIdentifier(e) { 1644 _makeDeclaredIdentifier(e) {
1638 if (e is VarExpression) { 1645 if (e is VarExpression) {
1639 return new DeclaredIdentifier(null, e.name, e.span); 1646 return new DeclaredIdentifier(null, e.name, e.span);
1640 } else if (e is DeclaredIdentifier) { 1647 } else if (e is DeclaredIdentifier) {
1641 return e; 1648 return e;
1642 } else { 1649 } else {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 int _pos = 0; 1688 int _pos = 0;
1682 next() { 1689 next() {
1683 var token = tokens[_pos]; 1690 var token = tokens[_pos];
1684 ++_pos; 1691 ++_pos;
1685 if (_pos == tokens.length) { 1692 if (_pos == tokens.length) {
1686 parser.tokenizer = previousTokenizer; 1693 parser.tokenizer = previousTokenizer;
1687 } 1694 }
1688 return token; 1695 return token;
1689 } 1696 }
1690 } 1697 }
OLDNEW
« no previous file with comments | « frog/member.dart ('k') | frog/presubmit.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698