OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |