| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 * Defines the tokens that are produced by the scanner, used by the parser, and | 6 * Defines the tokens that are produced by the scanner, used by the parser, and |
| 7 * referenced from the [AST structure](ast.dart). | 7 * referenced from the [AST structure](ast.dart). |
| 8 */ | 8 */ |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 | 10 |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 * The next token in the token stream. | 532 * The next token in the token stream. |
| 533 */ | 533 */ |
| 534 Token _next; | 534 Token _next; |
| 535 | 535 |
| 536 /** | 536 /** |
| 537 * Initialize a newly created token to have the given [type] and [offset]. | 537 * Initialize a newly created token to have the given [type] and [offset]. |
| 538 */ | 538 */ |
| 539 SimpleToken(this.type, this.offset); | 539 SimpleToken(this.type, this.offset); |
| 540 | 540 |
| 541 @override | 541 @override |
| 542 int get charCount => length; |
| 543 |
| 544 @override |
| 545 int get charOffset => offset; |
| 546 |
| 547 @override |
| 548 int get charEnd => end; |
| 549 |
| 550 @override |
| 542 int get end => offset + length; | 551 int get end => offset + length; |
| 543 | 552 |
| 544 @override | 553 @override |
| 554 bool get isEof => type == TokenType.EOF; |
| 555 |
| 556 @override |
| 545 bool get isOperator => type.isOperator; | 557 bool get isOperator => type.isOperator; |
| 546 | 558 |
| 547 @override | 559 @override |
| 548 bool get isSynthetic => length == 0; | 560 bool get isSynthetic => length == 0; |
| 549 | 561 |
| 550 @override | 562 @override |
| 551 bool get isUserDefinableOperator => type.isUserDefinableOperator; | 563 bool get isUserDefinableOperator => type.isUserDefinableOperator; |
| 552 | 564 |
| 553 @override | 565 @override |
| 554 Keyword get keyword => null; | 566 Keyword get keyword => null; |
| 555 | 567 |
| 556 @override | 568 @override |
| 569 int get kind => type.kind; |
| 570 |
| 571 @override |
| 557 int get length => lexeme.length; | 572 int get length => lexeme.length; |
| 558 | 573 |
| 559 @override | 574 @override |
| 560 String get lexeme => type.lexeme; | 575 String get lexeme => type.lexeme; |
| 561 | 576 |
| 562 @override | 577 @override |
| 563 Token get next => _next; | 578 Token get next => _next; |
| 564 | 579 |
| 565 @override | 580 @override |
| 566 CommentToken get precedingComments => null; | 581 CommentToken get precedingComments => null; |
| 567 | 582 |
| 568 @override | 583 @override |
| 584 String get stringValue => type.stringValue; |
| 585 |
| 586 @override |
| 569 void applyDelta(int delta) { | 587 void applyDelta(int delta) { |
| 570 offset += delta; | 588 offset += delta; |
| 571 } | 589 } |
| 572 | 590 |
| 573 @override | 591 @override |
| 574 Token copy() => new Token(type, offset); | 592 Token copy() => new Token(type, offset); |
| 575 | 593 |
| 576 @override | 594 @override |
| 577 Token copyComments(Token token) { | 595 Token copyComments(Token token) { |
| 578 if (token == null) { | 596 if (token == null) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 * precede and follow it, acting as a link in a doubly linked list of tokens. | 754 * precede and follow it, acting as a link in a doubly linked list of tokens. |
| 737 * | 755 * |
| 738 * Clients may not extend, implement or mix-in this class. | 756 * Clients may not extend, implement or mix-in this class. |
| 739 */ | 757 */ |
| 740 abstract class Token implements SyntacticEntity { | 758 abstract class Token implements SyntacticEntity { |
| 741 /** | 759 /** |
| 742 * Initialize a newly created token to have the given [type] and [offset]. | 760 * Initialize a newly created token to have the given [type] and [offset]. |
| 743 */ | 761 */ |
| 744 factory Token(TokenType type, int offset) = SimpleToken; | 762 factory Token(TokenType type, int offset) = SimpleToken; |
| 745 | 763 |
| 764 /** |
| 765 * The number of characters parsed by this token. |
| 766 */ |
| 767 int get charCount; |
| 768 |
| 769 /** |
| 770 * The character offset of the start of this token within the source text. |
| 771 */ |
| 772 int get charOffset; |
| 773 |
| 774 /** |
| 775 * The character offset of the end of this token within the source text. |
| 776 */ |
| 777 int get charEnd; |
| 778 |
| 746 @override | 779 @override |
| 747 int get end; | 780 int get end; |
| 748 | 781 |
| 749 /** | 782 /** |
| 783 * Return `true` if this token represents an end of file. |
| 784 */ |
| 785 bool get isEof; |
| 786 |
| 787 /** |
| 750 * Return `true` if this token represents an operator. | 788 * Return `true` if this token represents an operator. |
| 751 */ | 789 */ |
| 752 bool get isOperator; | 790 bool get isOperator; |
| 753 | 791 |
| 754 /** | 792 /** |
| 755 * Return `true` if this token is a synthetic token. A synthetic token is a | 793 * Return `true` if this token is a synthetic token. A synthetic token is a |
| 756 * token that was introduced by the parser in order to recover from an error | 794 * token that was introduced by the parser in order to recover from an error |
| 757 * in the code. | 795 * in the code. |
| 758 */ | 796 */ |
| 759 bool get isSynthetic; | 797 bool get isSynthetic; |
| 760 | 798 |
| 761 /** | 799 /** |
| 762 * Return `true` if this token represents an operator that can be defined by | 800 * Return `true` if this token represents an operator that can be defined by |
| 763 * users. | 801 * users. |
| 764 */ | 802 */ |
| 765 bool get isUserDefinableOperator; | 803 bool get isUserDefinableOperator; |
| 766 | 804 |
| 767 /** | 805 /** |
| 768 * Return the keyword, if a keyword token, or `null` otherwise. | 806 * Return the keyword, if a keyword token, or `null` otherwise. |
| 769 */ | 807 */ |
| 770 Keyword get keyword; | 808 Keyword get keyword; |
| 771 | 809 |
| 810 /** |
| 811 * The kind enum of this token as determined by its [type]. |
| 812 */ |
| 813 int get kind; |
| 814 |
| 772 @override | 815 @override |
| 773 int get length; | 816 int get length; |
| 774 | 817 |
| 775 /** | 818 /** |
| 776 * Return the lexeme that represents this token. | 819 * Return the lexeme that represents this token. |
| 777 */ | 820 */ |
| 778 String get lexeme; | 821 String get lexeme; |
| 779 | 822 |
| 780 /** | 823 /** |
| 781 * Return the next token in the token stream. | 824 * Return the next token in the token stream. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 807 * Return the previous token in the token stream. | 850 * Return the previous token in the token stream. |
| 808 */ | 851 */ |
| 809 Token get previous; | 852 Token get previous; |
| 810 | 853 |
| 811 /** | 854 /** |
| 812 * Set the previous token in the token stream to the given [token]. | 855 * Set the previous token in the token stream to the given [token]. |
| 813 */ | 856 */ |
| 814 void set previous(Token token); | 857 void set previous(Token token); |
| 815 | 858 |
| 816 /** | 859 /** |
| 860 * For symbol and keyword tokens, returns the string value represented by this |
| 861 * token. For [StringToken]s this method returns [:null:]. |
| 862 * |
| 863 * For [SymbolToken]s and [KeywordToken]s, the string value is a compile-time |
| 864 * constant originating in the [TokenType] or in the [Keyword] instance. |
| 865 * This allows testing for keywords and symbols using [:identical:], e.g., |
| 866 * [:identical('class', token.value):]. |
| 867 * |
| 868 * Note that returning [:null:] for string tokens is important to identify |
| 869 * symbols and keywords, we cannot use [lexeme] instead. The string literal |
| 870 * "$a($b" |
| 871 * produces ..., SymbolToken($), StringToken(a), StringToken((), ... |
| 872 * |
| 873 * After parsing the identifier 'a', the parser tests for a function |
| 874 * declaration using [:identical(next.stringValue, '('):], which (rightfully) |
| 875 * returns false because stringValue returns [:null:]. |
| 876 */ |
| 877 String get stringValue; |
| 878 |
| 879 /** |
| 817 * Return the type of the token. | 880 * Return the type of the token. |
| 818 */ | 881 */ |
| 819 TokenType get type; | 882 TokenType get type; |
| 820 | 883 |
| 821 /** | 884 /** |
| 822 * Apply (add) the given [delta] to this token's offset. | 885 * Apply (add) the given [delta] to this token's offset. |
| 823 */ | 886 */ |
| 824 void applyDelta(int delta); | 887 void applyDelta(int delta); |
| 825 | 888 |
| 826 /** | 889 /** |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 * | 1078 * |
| 1016 * Clients may not extend, implement or mix-in this class. | 1079 * Clients may not extend, implement or mix-in this class. |
| 1017 */ | 1080 */ |
| 1018 class TokenType { | 1081 class TokenType { |
| 1019 /** | 1082 /** |
| 1020 * The type of the token that marks the start or end of the input. | 1083 * The type of the token that marks the start or end of the input. |
| 1021 */ | 1084 */ |
| 1022 static const TokenType EOF = | 1085 static const TokenType EOF = |
| 1023 const TokenType('', 'EOF', NO_PRECEDENCE, EOF_TOKEN); | 1086 const TokenType('', 'EOF', NO_PRECEDENCE, EOF_TOKEN); |
| 1024 | 1087 |
| 1025 static const TokenType DOUBLE = | 1088 static const TokenType DOUBLE = const TokenType( |
| 1026 const TokenType('double', 'DOUBLE', NO_PRECEDENCE, DOUBLE_TOKEN); | 1089 'double', 'DOUBLE', NO_PRECEDENCE, DOUBLE_TOKEN, |
| 1090 stringValue: null); |
| 1027 | 1091 |
| 1028 static const TokenType HEXADECIMAL = const TokenType( | 1092 static const TokenType HEXADECIMAL = const TokenType( |
| 1029 'hexadecimal', 'HEXADECIMAL', NO_PRECEDENCE, HEXADECIMAL_TOKEN); | 1093 'hexadecimal', 'HEXADECIMAL', NO_PRECEDENCE, HEXADECIMAL_TOKEN, |
| 1094 stringValue: null); |
| 1030 | 1095 |
| 1031 static const TokenType IDENTIFIER = const TokenType( | 1096 static const TokenType IDENTIFIER = const TokenType( |
| 1032 'identifier', 'STRING_INT', NO_PRECEDENCE, IDENTIFIER_TOKEN); | 1097 'identifier', 'STRING_INT', NO_PRECEDENCE, IDENTIFIER_TOKEN, |
| 1098 stringValue: null); |
| 1033 | 1099 |
| 1034 static const TokenType INT = | 1100 static const TokenType INT = const TokenType( |
| 1035 const TokenType('int', 'INT', NO_PRECEDENCE, INT_TOKEN); | 1101 'int', 'INT', NO_PRECEDENCE, INT_TOKEN, |
| 1102 stringValue: null); |
| 1036 | 1103 |
| 1037 static const TokenType MULTI_LINE_COMMENT = const TokenType( | 1104 static const TokenType MULTI_LINE_COMMENT = const TokenType( |
| 1038 'comment', 'MULTI_LINE_COMMENT', NO_PRECEDENCE, COMMENT_TOKEN); | 1105 'comment', 'MULTI_LINE_COMMENT', NO_PRECEDENCE, COMMENT_TOKEN, |
| 1106 stringValue: null); |
| 1039 | 1107 |
| 1040 static const TokenType SCRIPT_TAG = | 1108 static const TokenType SCRIPT_TAG = |
| 1041 const TokenType('script', 'SCRIPT_TAG', NO_PRECEDENCE, SCRIPT_TOKEN); | 1109 const TokenType('script', 'SCRIPT_TAG', NO_PRECEDENCE, SCRIPT_TOKEN); |
| 1042 | 1110 |
| 1043 static const TokenType SINGLE_LINE_COMMENT = const TokenType( | 1111 static const TokenType SINGLE_LINE_COMMENT = const TokenType( |
| 1044 'comment', 'SINGLE_LINE_COMMENT', NO_PRECEDENCE, COMMENT_TOKEN); | 1112 'comment', 'SINGLE_LINE_COMMENT', NO_PRECEDENCE, COMMENT_TOKEN, |
| 1113 stringValue: null); |
| 1045 | 1114 |
| 1046 static const TokenType STRING = | 1115 static const TokenType STRING = const TokenType( |
| 1047 const TokenType('string', 'STRING', NO_PRECEDENCE, STRING_TOKEN); | 1116 'string', 'STRING', NO_PRECEDENCE, STRING_TOKEN, |
| 1117 stringValue: null); |
| 1048 | 1118 |
| 1049 static const TokenType AMPERSAND = const TokenType( | 1119 static const TokenType AMPERSAND = const TokenType( |
| 1050 '&', 'AMPERSAND', BITWISE_AND_PRECEDENCE, AMPERSAND_TOKEN, | 1120 '&', 'AMPERSAND', BITWISE_AND_PRECEDENCE, AMPERSAND_TOKEN, |
| 1051 isOperator: true, isUserDefinableOperator: true); | 1121 isOperator: true, isUserDefinableOperator: true); |
| 1052 | 1122 |
| 1053 static const TokenType AMPERSAND_AMPERSAND = const TokenType('&&', | 1123 static const TokenType AMPERSAND_AMPERSAND = const TokenType('&&', |
| 1054 'AMPERSAND_AMPERSAND', LOGICAL_AND_PRECEDENCE, AMPERSAND_AMPERSAND_TOKEN, | 1124 'AMPERSAND_AMPERSAND', LOGICAL_AND_PRECEDENCE, AMPERSAND_AMPERSAND_TOKEN, |
| 1055 isOperator: true); | 1125 isOperator: true); |
| 1056 | 1126 |
| 1057 // This is not yet part of the language and not supported by fasta | 1127 // This is not yet part of the language and not supported by fasta |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 static const TokenType BACKSLASH = | 1355 static const TokenType BACKSLASH = |
| 1286 const TokenType('\\', 'BACKSLASH', NO_PRECEDENCE, BACKSLASH_TOKEN); | 1356 const TokenType('\\', 'BACKSLASH', NO_PRECEDENCE, BACKSLASH_TOKEN); |
| 1287 | 1357 |
| 1288 static const TokenType PERIOD_PERIOD_PERIOD = const TokenType( | 1358 static const TokenType PERIOD_PERIOD_PERIOD = const TokenType( |
| 1289 '...', 'PERIOD_PERIOD_PERIOD', NO_PRECEDENCE, PERIOD_PERIOD_PERIOD_TOKEN); | 1359 '...', 'PERIOD_PERIOD_PERIOD', NO_PRECEDENCE, PERIOD_PERIOD_PERIOD_TOKEN); |
| 1290 | 1360 |
| 1291 static const TokenType GENERIC_METHOD_TYPE_LIST = const TokenType( | 1361 static const TokenType GENERIC_METHOD_TYPE_LIST = const TokenType( |
| 1292 'generic_comment_list', | 1362 'generic_comment_list', |
| 1293 'GENERIC_METHOD_TYPE_LIST', | 1363 'GENERIC_METHOD_TYPE_LIST', |
| 1294 NO_PRECEDENCE, | 1364 NO_PRECEDENCE, |
| 1295 GENERIC_METHOD_TYPE_LIST_TOKEN); | 1365 GENERIC_METHOD_TYPE_LIST_TOKEN, |
| 1366 stringValue: null); |
| 1296 | 1367 |
| 1297 static const TokenType GENERIC_METHOD_TYPE_ASSIGN = const TokenType( | 1368 static const TokenType GENERIC_METHOD_TYPE_ASSIGN = const TokenType( |
| 1298 'generic_comment_assign', | 1369 'generic_comment_assign', |
| 1299 'GENERIC_METHOD_TYPE_ASSIGN', | 1370 'GENERIC_METHOD_TYPE_ASSIGN', |
| 1300 NO_PRECEDENCE, | 1371 NO_PRECEDENCE, |
| 1301 GENERIC_METHOD_TYPE_ASSIGN_TOKEN); | 1372 GENERIC_METHOD_TYPE_ASSIGN_TOKEN, |
| 1373 stringValue: null); |
| 1302 | 1374 |
| 1303 static const TokenType AS = Keyword.AS; | 1375 static const TokenType AS = Keyword.AS; |
| 1304 | 1376 |
| 1305 static const TokenType IS = Keyword.IS; | 1377 static const TokenType IS = Keyword.IS; |
| 1306 | 1378 |
| 1307 /** | 1379 /** |
| 1308 * Token type used by error tokens. | 1380 * Token type used by error tokens. |
| 1309 */ | 1381 */ |
| 1310 static const TokenType BAD_INPUT = const TokenType( | 1382 static const TokenType BAD_INPUT = const TokenType( |
| 1311 'malformed input', 'BAD_INPUT', NO_PRECEDENCE, BAD_INPUT_TOKEN); | 1383 'malformed input', 'BAD_INPUT', NO_PRECEDENCE, BAD_INPUT_TOKEN, |
| 1384 stringValue: null); |
| 1312 | 1385 |
| 1313 /** | 1386 /** |
| 1314 * Token type used by synthetic tokens that are created during parser | 1387 * Token type used by synthetic tokens that are created during parser |
| 1315 * recovery (non-analyzer use case). | 1388 * recovery (non-analyzer use case). |
| 1316 */ | 1389 */ |
| 1317 static const TokenType RECOVERY = | 1390 static const TokenType RECOVERY = const TokenType( |
| 1318 const TokenType('recovery', 'RECOVERY', NO_PRECEDENCE, RECOVERY_TOKEN); | 1391 'recovery', 'RECOVERY', NO_PRECEDENCE, RECOVERY_TOKEN, |
| 1392 stringValue: null); |
| 1319 | 1393 |
| 1320 // TODO(danrubel): "all" is misleading | 1394 // TODO(danrubel): "all" is misleading |
| 1321 // because this list does not include all TokenType instances. | 1395 // because this list does not include all TokenType instances. |
| 1322 static const List<TokenType> all = const <TokenType>[ | 1396 static const List<TokenType> all = const <TokenType>[ |
| 1323 TokenType.EOF, | 1397 TokenType.EOF, |
| 1324 TokenType.DOUBLE, | 1398 TokenType.DOUBLE, |
| 1325 TokenType.HEXADECIMAL, | 1399 TokenType.HEXADECIMAL, |
| 1326 TokenType.IDENTIFIER, | 1400 TokenType.IDENTIFIER, |
| 1327 TokenType.INT, | 1401 TokenType.INT, |
| 1328 TokenType.MULTI_LINE_COMMENT, | 1402 TokenType.MULTI_LINE_COMMENT, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1432 * The name of the token type. | 1506 * The name of the token type. |
| 1433 */ | 1507 */ |
| 1434 final String name; | 1508 final String name; |
| 1435 | 1509 |
| 1436 /** | 1510 /** |
| 1437 * The precedence of this type of token, | 1511 * The precedence of this type of token, |
| 1438 * or `0` if the token does not represent an operator. | 1512 * or `0` if the token does not represent an operator. |
| 1439 */ | 1513 */ |
| 1440 final int precedence; | 1514 final int precedence; |
| 1441 | 1515 |
| 1516 /** |
| 1517 * See [Token.stringValue] for an explanation. |
| 1518 */ |
| 1519 final String stringValue; |
| 1520 |
| 1442 const TokenType(this.lexeme, this.name, this.precedence, this.kind, | 1521 const TokenType(this.lexeme, this.name, this.precedence, this.kind, |
| 1443 {this.isOperator: false, this.isUserDefinableOperator: false}); | 1522 {this.isOperator: false, |
| 1523 this.isUserDefinableOperator: false, |
| 1524 String stringValue: 'unspecified'}) |
| 1525 : this.stringValue = stringValue == 'unspecified' ? lexeme : stringValue; |
| 1444 | 1526 |
| 1445 /** | 1527 /** |
| 1446 * Return `true` if this type of token represents an additive operator. | 1528 * Return `true` if this type of token represents an additive operator. |
| 1447 */ | 1529 */ |
| 1448 bool get isAdditiveOperator => precedence == ADDITIVE_PRECEDENCE; | 1530 bool get isAdditiveOperator => precedence == ADDITIVE_PRECEDENCE; |
| 1449 | 1531 |
| 1450 /** | 1532 /** |
| 1451 * Return `true` if this type of token represents an assignment operator. | 1533 * Return `true` if this type of token represents an assignment operator. |
| 1452 */ | 1534 */ |
| 1453 bool get isAssignmentOperator => precedence == ASSIGNMENT_PRECEDENCE; | 1535 bool get isAssignmentOperator => precedence == ASSIGNMENT_PRECEDENCE; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 | 1638 |
| 1557 void set precedingComments(CommentToken comment) { | 1639 void set precedingComments(CommentToken comment) { |
| 1558 _precedingComment = comment; | 1640 _precedingComment = comment; |
| 1559 _setCommentParent(_precedingComment); | 1641 _setCommentParent(_precedingComment); |
| 1560 } | 1642 } |
| 1561 | 1643 |
| 1562 @override | 1644 @override |
| 1563 Token copy() => | 1645 Token copy() => |
| 1564 new TokenWithComment(type, offset, copyComments(precedingComments)); | 1646 new TokenWithComment(type, offset, copyComments(precedingComments)); |
| 1565 } | 1647 } |
| OLD | NEW |