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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 } else { | 454 } else { |
455 name = new Identifier('', names[0].span); | 455 name = new Identifier('', names[0].span); |
456 } | 456 } |
457 } | 457 } |
458 | 458 |
459 if (names.length > 1) { | 459 if (names.length > 1) { |
460 // TODO(jimhug): This is nasty to support and currently unused. | 460 // TODO(jimhug): This is nasty to support and currently unused. |
461 _error('unsupported qualified name for factory', names[0].span); | 461 _error('unsupported qualified name for factory', names[0].span); |
462 } | 462 } |
463 type = new NameTypeReference(false, names[0], null, names[0].span); | 463 type = new NameTypeReference(false, names[0], null, names[0].span); |
464 var di = new DeclaredIdentifier(type, name, _makeSpan(start)); | 464 var di = new DeclaredIdentifier(type, name, false, _makeSpan(start)); |
465 return finishDefinition(start, [factoryToken], di); | 465 return finishDefinition(start, [factoryToken], di); |
466 } | 466 } |
467 | 467 |
468 /////////////////////////////////////////////////////////////////// | 468 /////////////////////////////////////////////////////////////////// |
469 // Statement productions | 469 // Statement productions |
470 /////////////////////////////////////////////////////////////////// | 470 /////////////////////////////////////////////////////////////////// |
471 Statement statement() { | 471 Statement statement() { |
472 switch (_peek()) { | 472 switch (_peek()) { |
473 case TokenKind.BREAK: | 473 case TokenKind.BREAK: |
474 return breakStatement(); | 474 return breakStatement(); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 } else { | 644 } else { |
645 var init = expression(); | 645 var init = expression(); |
646 // Weird code here is needed to handle generic type and for in | 646 // Weird code here is needed to handle generic type and for in |
647 // TODO(jmesserly): unify with block in finishExpressionAsStatement | 647 // TODO(jmesserly): unify with block in finishExpressionAsStatement |
648 if (_peekKind(TokenKind.COMMA) && _isBin(init, TokenKind.LT)) { | 648 if (_peekKind(TokenKind.COMMA) && _isBin(init, TokenKind.LT)) { |
649 _eat(TokenKind.COMMA); | 649 _eat(TokenKind.COMMA); |
650 var baseType = _makeType(init.x); | 650 var baseType = _makeType(init.x); |
651 var typeArgs = [_makeType(init.y)]; | 651 var typeArgs = [_makeType(init.y)]; |
652 var gt = _finishTypeArguments(baseType, 0, typeArgs); | 652 var gt = _finishTypeArguments(baseType, 0, typeArgs); |
653 var name = identifier(); | 653 var name = identifier(); |
654 init = new DeclaredIdentifier(gt, name, _makeSpan(init.span.start)); | 654 init = new DeclaredIdentifier(gt, name, false, _makeSpan(init.span.start
)); |
655 } | 655 } |
656 | 656 |
657 if (_maybeEat(TokenKind.IN)) { | 657 if (_maybeEat(TokenKind.IN)) { |
658 return _finishForIn(start, _makeDeclaredIdentifier(init)); | 658 return _finishForIn(start, _makeDeclaredIdentifier(init)); |
659 } else { | 659 } else { |
660 return finishExpressionAsStatement(init); | 660 return finishExpressionAsStatement(init); |
661 } | 661 } |
662 } | 662 } |
663 } | 663 } |
664 | 664 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 } | 838 } |
839 } | 839 } |
840 | 840 |
841 infixExpression(int precedence) { | 841 infixExpression(int precedence) { |
842 return finishInfixExpression(unaryExpression(), precedence); | 842 return finishInfixExpression(unaryExpression(), precedence); |
843 } | 843 } |
844 | 844 |
845 _finishDeclaredId(type) { | 845 _finishDeclaredId(type) { |
846 var name = identifier(); | 846 var name = identifier(); |
847 return finishPostfixExpression( | 847 return finishPostfixExpression( |
848 new DeclaredIdentifier(type, name, _makeSpan(type.span.start))); | 848 new DeclaredIdentifier(type, name, false, _makeSpan(type.span.start))); |
849 } | 849 } |
850 | 850 |
851 /** | 851 /** |
852 * Takes an initial binary expression of A < B and turns it into a | 852 * Takes an initial binary expression of A < B and turns it into a |
853 * declared identifier included the A < B piece in the type. | 853 * declared identifier included the A < B piece in the type. |
854 */ | 854 */ |
855 _fixAsType(BinaryExpression x) { | 855 _fixAsType(BinaryExpression x) { |
856 assert(_isBin(x, TokenKind.LT)); | 856 assert(_isBin(x, TokenKind.LT)); |
857 // TODO(jimhug): good errors when expectations are violated | 857 // TODO(jimhug): good errors when expectations are violated |
858 if (_maybeEat(TokenKind.GT)) { | 858 if (_maybeEat(TokenKind.GT)) { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 // must be forbidden when parsing initializers. | 1012 // must be forbidden when parsing initializers. |
1013 // TODO(jmesserly): is this still needed? | 1013 // TODO(jmesserly): is this still needed? |
1014 case TokenKind.ARROW: | 1014 case TokenKind.ARROW: |
1015 case TokenKind.LBRACE: | 1015 case TokenKind.LBRACE: |
1016 return expr; | 1016 return expr; |
1017 | 1017 |
1018 default: | 1018 default: |
1019 if (_peekIdentifier()) { | 1019 if (_peekIdentifier()) { |
1020 return finishPostfixExpression( | 1020 return finishPostfixExpression( |
1021 new DeclaredIdentifier(_makeType(expr), identifier(), | 1021 new DeclaredIdentifier(_makeType(expr), identifier(), |
1022 _makeSpan(expr.span.start))); | 1022 false, _makeSpan(expr.span.start))); |
1023 } else { | 1023 } else { |
1024 return expr; | 1024 return expr; |
1025 } | 1025 } |
1026 } | 1026 } |
1027 } | 1027 } |
1028 | 1028 |
1029 finishCallOrLambdaExpression(expr) { | 1029 finishCallOrLambdaExpression(expr) { |
1030 if (_atClosureParameters()) { | 1030 if (_atClosureParameters()) { |
1031 var formals = formalParameterList(); | 1031 var formals = formalParameterList(); |
1032 var body = functionBody(true); | 1032 var body = functionBody(true); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 return null; | 1315 return null; |
1316 } | 1316 } |
1317 return new Identifier(name, _makeSpan(start)); | 1317 return new Identifier(name, _makeSpan(start)); |
1318 } | 1318 } |
1319 | 1319 |
1320 // always includes this and ... as legal names to simplify other code. | 1320 // always includes this and ... as legal names to simplify other code. |
1321 declaredIdentifier([bool includeOperators=false]) { | 1321 declaredIdentifier([bool includeOperators=false]) { |
1322 int start = _peekToken.start; | 1322 int start = _peekToken.start; |
1323 var myType = null; | 1323 var myType = null; |
1324 var name = _specialIdentifier(includeOperators); | 1324 var name = _specialIdentifier(includeOperators); |
| 1325 bool isFinal = false; |
1325 if (name == null) { | 1326 if (name == null) { |
1326 myType = type(); | 1327 myType = type(); |
1327 name = _specialIdentifier(includeOperators); | 1328 name = _specialIdentifier(includeOperators); |
1328 if (name == null) { | 1329 if (name == null) { |
1329 if (_peekIdentifier()) { | 1330 if (_peekIdentifier()) { |
1330 name = identifier(); | 1331 name = identifier(); |
1331 } else if (myType is NameTypeReference && myType.names == null) { | 1332 } else if (myType is NameTypeReference && myType.names == null) { |
1332 name = _typeAsIdentifier(myType); | 1333 name = _typeAsIdentifier(myType); |
| 1334 isFinal = myType.isFinal; |
1333 myType = null; | 1335 myType = null; |
1334 } else { | 1336 } else { |
1335 // TODO(jimhug): Where do these errors get handled? | 1337 // TODO(jimhug): Where do these errors get handled? |
1336 } | 1338 } |
1337 } | 1339 } |
1338 } | 1340 } |
1339 return new DeclaredIdentifier(myType, name, _makeSpan(start)); | 1341 return new DeclaredIdentifier(myType, name, isFinal, _makeSpan(start)); |
1340 } | 1342 } |
1341 | 1343 |
1342 finishNewExpression(int start, bool isConst) { | 1344 finishNewExpression(int start, bool isConst) { |
1343 var type = type(); | 1345 var type = type(); |
1344 var name = null; | 1346 var name = null; |
1345 if (_maybeEat(TokenKind.DOT)) { | 1347 if (_maybeEat(TokenKind.DOT)) { |
1346 name = identifier(); | 1348 name = identifier(); |
1347 } | 1349 } |
1348 var args = arguments(); | 1350 var args = arguments(); |
1349 return new NewExpression(isConst, type, name, args, _makeSpan(start)); | 1351 return new NewExpression(isConst, type, name, args, _makeSpan(start)); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 } | 1669 } |
1668 var span = new SourceSpan(expr.span.file, expr.span.start, body.span.end); | 1670 var span = new SourceSpan(expr.span.file, expr.span.start, body.span.end); |
1669 var func = new FunctionDefinition(null, type, name, formals, null, null, | 1671 var func = new FunctionDefinition(null, type, name, formals, null, null, |
1670 body, span); | 1672 body, span); |
1671 return new LambdaExpression(func, func.span); | 1673 return new LambdaExpression(func, func.span); |
1672 } | 1674 } |
1673 | 1675 |
1674 /** Converts an expression to a [DeclaredIdentifier]. */ | 1676 /** Converts an expression to a [DeclaredIdentifier]. */ |
1675 _makeDeclaredIdentifier(e) { | 1677 _makeDeclaredIdentifier(e) { |
1676 if (e is VarExpression) { | 1678 if (e is VarExpression) { |
1677 return new DeclaredIdentifier(null, e.name, e.span); | 1679 return new DeclaredIdentifier(null, e.name, false, e.span); |
1678 } else if (e is DeclaredIdentifier) { | 1680 } else if (e is DeclaredIdentifier) { |
1679 return e; | 1681 return e; |
1680 } else { | 1682 } else { |
1681 _error('expected declared identifier'); | 1683 _error('expected declared identifier'); |
1682 return new DeclaredIdentifier(null, null, e.span); | 1684 return new DeclaredIdentifier(null, null, false, e.span); |
1683 } | 1685 } |
1684 } | 1686 } |
1685 | 1687 |
1686 /** Converts an expression into a label. */ | 1688 /** Converts an expression into a label. */ |
1687 _makeLabel(expr) { | 1689 _makeLabel(expr) { |
1688 if (expr is VarExpression) { | 1690 if (expr is VarExpression) { |
1689 return expr.name; | 1691 return expr.name; |
1690 } else { | 1692 } else { |
1691 _errorExpected('label'); | 1693 _errorExpected('label'); |
1692 return null; | 1694 return null; |
(...skipping 26 matching lines...) Expand all Loading... |
1719 int _pos = 0; | 1721 int _pos = 0; |
1720 next() { | 1722 next() { |
1721 var token = tokens[_pos]; | 1723 var token = tokens[_pos]; |
1722 ++_pos; | 1724 ++_pos; |
1723 if (_pos == tokens.length) { | 1725 if (_pos == tokens.length) { |
1724 parser.tokenizer = previousTokenizer; | 1726 parser.tokenizer = previousTokenizer; |
1725 } | 1727 } |
1726 return token; | 1728 return token; |
1727 } | 1729 } |
1728 } | 1730 } |
OLD | NEW |