Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 interface Scanner { | 5 interface Scanner { |
| 6 Token tokenize(); | 6 Token tokenize(); |
| 7 } | 7 } |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * Common base class for a Dart scanner. | 10 * Common base class for a Dart scanner. |
| 11 */ | 11 */ |
| 12 class AbstractScanner<T extends SourceString> implements Scanner { | 12 class AbstractScanner<T extends SourceString> implements Scanner { |
| 13 abstract int advance(); | 13 abstract int advance(); |
| 14 abstract int nextByte(); | 14 abstract int nextByte(); |
| 15 | |
| 16 /** | |
| 17 * Returns the current character or byte depending on the underlying input | |
| 18 * kind. For example, [StringScanner] operates on [String] and thus returns | |
| 19 * characters whereas [ByteArrayScanner] operators on byte arrays and thus | |
|
ahe
2012/06/25 08:12:37
... characters (Unicode codepoints represented as
Johnni Winther
2012/06/25 10:40:00
Done.
| |
| 20 * returns bytes. | |
| 21 */ | |
| 15 abstract int peek(); | 22 abstract int peek(); |
| 23 | |
| 24 /** | |
| 25 * Appends a fixed token based on whether the current char is [choice] or not. | |
| 26 * If the current char is [choice] a fixed token whose kind and content | |
| 27 * is determined by [yes] is appended, otherwise a fixed token whose kind | |
| 28 * and content is determined by [no] is appended. */ | |
|
ahe
2012/06/25 08:12:37
*/ on its own line.
Johnni Winther
2012/06/25 10:40:00
Done.
| |
| 16 abstract int select(int choice, PrecedenceInfo yes, PrecedenceInfo no); | 29 abstract int select(int choice, PrecedenceInfo yes, PrecedenceInfo no); |
| 30 | |
| 31 /** | |
| 32 * Appends a fixed token whose kind and content is determined by [info]. | |
| 33 */ | |
| 17 abstract void appendPrecedenceToken(PrecedenceInfo info); | 34 abstract void appendPrecedenceToken(PrecedenceInfo info); |
| 35 | |
| 36 /** | |
| 37 * Appends a token whose kind is determined by [info] and content is [value]. | |
| 38 */ | |
| 18 abstract void appendStringToken(PrecedenceInfo info, String value); | 39 abstract void appendStringToken(PrecedenceInfo info, String value); |
| 40 | |
| 41 /** | |
| 42 * Appends a token whose kind is determined by [info] and content is defined | |
| 43 * by the SourceString [value]. | |
| 44 */ | |
| 19 abstract void appendByteStringToken(PrecedenceInfo info, T value); | 45 abstract void appendByteStringToken(PrecedenceInfo info, T value); |
| 46 | |
| 47 /** | |
| 48 * Appends a keyword token whose kind is determined by [keyword]. | |
| 49 */ | |
| 20 abstract void appendKeywordToken(Keyword keyword); | 50 abstract void appendKeywordToken(Keyword keyword); |
| 21 abstract void appendWhiteSpace(int next); | 51 abstract void appendWhiteSpace(int next); |
| 22 abstract void appendEofToken(); | 52 abstract void appendEofToken(); |
| 53 | |
| 54 /** | |
| 55 * Creates an ascii SourceString whose content begins at the source byte | |
|
ahe
2012/06/25 08:12:37
ascii -> ASCII
Johnni Winther
2012/06/25 10:40:00
Done.
| |
| 56 * offset [start] and ends at [offset] bytes from the current byte offset of | |
| 57 * the scanner. For example, if the current byte offset is 10, | |
| 58 * [:asciiString(0,-1):] creates an ascii SourceString whose content is found | |
|
ahe
2012/06/25 08:12:37
Ditto.
Johnni Winther
2012/06/25 10:40:00
Done.
| |
| 59 * at the [0,9[ byte interval of the source text. | |
| 60 */ | |
| 23 abstract T asciiString(int start, int offset); | 61 abstract T asciiString(int start, int offset); |
| 24 abstract T utf8String(int start, int offset); | 62 abstract T utf8String(int start, int offset); |
| 25 abstract Token firstToken(); | 63 abstract Token firstToken(); |
| 26 abstract Token previousToken(); | 64 abstract Token previousToken(); |
| 27 abstract void beginToken(); | 65 abstract void beginToken(); |
| 28 abstract void addToCharOffset(int offset); | 66 abstract void addToCharOffset(int offset); |
| 29 abstract int get charOffset(); | 67 abstract int get charOffset(); |
| 30 abstract int get byteOffset(); | 68 abstract int get byteOffset(); |
| 31 abstract void appendBeginGroup(PrecedenceInfo info, String value); | 69 abstract void appendBeginGroup(PrecedenceInfo info, String value); |
| 32 abstract int appendEndGroup(PrecedenceInfo info, String value, int openKind); | 70 abstract int appendEndGroup(PrecedenceInfo info, String value, int openKind); |
| 33 abstract void appendGt(PrecedenceInfo info, String value); | 71 abstract void appendGt(PrecedenceInfo info, String value); |
| 34 abstract void appendGtGt(PrecedenceInfo info, String value); | 72 abstract void appendGtGt(PrecedenceInfo info, String value); |
| 35 abstract void appendGtGtGt(PrecedenceInfo info, String value); | 73 abstract void appendGtGtGt(PrecedenceInfo info, String value); |
| 74 abstract void appendComment(); | |
| 36 | 75 |
| 37 /** | 76 /** |
| 38 * We call this method to discard '<' from the "grouping" stack | 77 * We call this method to discard '<' from the "grouping" stack |
| 39 * (maintained by subclasses). | 78 * (maintained by subclasses). |
| 40 * | 79 * |
| 41 * [PartialParser.skipExpression] relies on the fact that we do not | 80 * [PartialParser.skipExpression] relies on the fact that we do not |
| 42 * create groups for stuff like: | 81 * create groups for stuff like: |
| 43 * [:a = b < c, d = e > f:]. | 82 * [:a = b < c, d = e > f:]. |
| 44 * | 83 * |
| 45 * In other words, this method is called when the scanner recognizes | 84 * In other words, this method is called when the scanner recognizes |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 } else { | 575 } else { |
| 537 appendPrecedenceToken(SLASH_INFO); | 576 appendPrecedenceToken(SLASH_INFO); |
| 538 return next; | 577 return next; |
| 539 } | 578 } |
| 540 } | 579 } |
| 541 | 580 |
| 542 int tokenizeSingleLineComment(int next) { | 581 int tokenizeSingleLineComment(int next) { |
| 543 while (true) { | 582 while (true) { |
| 544 next = advance(); | 583 next = advance(); |
| 545 if ($LF === next || $CR === next || $EOF === next) { | 584 if ($LF === next || $CR === next || $EOF === next) { |
| 585 appendComment(); | |
| 546 return next; | 586 return next; |
| 547 } | 587 } |
| 548 } | 588 } |
| 549 } | 589 } |
| 550 | 590 |
| 551 int tokenizeMultiLineComment(int next) { | 591 int tokenizeMultiLineComment(int next) { |
| 552 int nesting = 1; | 592 int nesting = 1; |
| 553 next = advance(); | 593 next = advance(); |
| 554 while (true) { | 594 while (true) { |
| 555 if ($EOF === next) { | 595 if ($EOF === next) { |
| 556 // TODO(ahe): Report error. | 596 // TODO(ahe): Report error. |
| 557 return next; | 597 return next; |
| 558 } else if ($STAR === next) { | 598 } else if ($STAR === next) { |
| 559 next = advance(); | 599 next = advance(); |
| 560 if ($SLASH === next) { | 600 if ($SLASH === next) { |
| 561 --nesting; | 601 --nesting; |
| 562 if (0 === nesting) { | 602 if (0 === nesting) { |
| 563 return advance(); | 603 next = advance(); |
| 604 appendComment(); | |
| 605 return next; | |
| 564 } else { | 606 } else { |
| 565 next = advance(); | 607 next = advance(); |
| 566 } | 608 } |
| 567 } | 609 } |
| 568 } else if ($SLASH === next) { | 610 } else if ($SLASH === next) { |
| 569 next = advance(); | 611 next = advance(); |
| 570 if ($STAR === next) { | 612 if ($STAR === next) { |
| 571 next = advance(); | 613 next = advance(); |
| 572 ++nesting; | 614 ++nesting; |
| 573 } | 615 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 throw new MalformedInputException("unterminated string literal", | 721 throw new MalformedInputException("unterminated string literal", |
| 680 charOffset); | 722 charOffset); |
| 681 } | 723 } |
| 682 next = advance(); | 724 next = advance(); |
| 683 } | 725 } |
| 684 appendByteStringToken(STRING_INFO, utf8String(start, 0)); | 726 appendByteStringToken(STRING_INFO, utf8String(start, 0)); |
| 685 return advance(); | 727 return advance(); |
| 686 } | 728 } |
| 687 | 729 |
| 688 int tokenizeStringInterpolation(int start) { | 730 int tokenizeStringInterpolation(int start) { |
| 689 beginToken(); | 731 appendByteStringToken(STRING_INFO, utf8String(start, -1)); |
| 732 beginToken(); // $ starts here. | |
| 690 int next = advance(); | 733 int next = advance(); |
| 691 if (next === $OPEN_CURLY_BRACKET) { | 734 if (next === $OPEN_CURLY_BRACKET) { |
| 692 return tokenizeInterpolatedExpression(next, start); | 735 return tokenizeInterpolatedExpression(next, start); |
| 693 } else { | 736 } else { |
| 694 return tokenizeInterpolatedIdentifier(next, start); | 737 return tokenizeInterpolatedIdentifier(next, start); |
| 695 } | 738 } |
| 696 } | 739 } |
| 697 | 740 |
| 698 int tokenizeInterpolatedExpression(int next, int start) { | 741 int tokenizeInterpolatedExpression(int next, int start) { |
| 699 appendByteStringToken(STRING_INFO, utf8String(start, -2)); | |
| 700 appendBeginGroup(STRING_INTERPOLATION_INFO, "\${"); | 742 appendBeginGroup(STRING_INTERPOLATION_INFO, "\${"); |
| 743 beginToken(); // The expression starts here. | |
| 701 next = advance(); | 744 next = advance(); |
| 702 while (next !== $EOF && next !== $STX) { | 745 while (next !== $EOF && next !== $STX) { |
| 703 next = bigSwitch(next); | 746 next = bigSwitch(next); |
| 704 } | 747 } |
| 705 if (next === $EOF) return next; | 748 if (next === $EOF) return next; |
| 706 return advance(); | 749 next = advance(); |
| 750 beginToken(); // The string interpolation suffix starts here. | |
| 751 return next; | |
| 707 } | 752 } |
| 708 | 753 |
| 709 int tokenizeInterpolatedIdentifier(int next, int start) { | 754 int tokenizeInterpolatedIdentifier(int next, int start) { |
| 710 appendByteStringToken(STRING_INFO, utf8String(start, -2)); | 755 appendPrecedenceToken(STRING_INTERPOLATION_IDENTIFIER_INFO); |
| 711 appendBeginGroup(STRING_INTERPOLATION_INFO, "\${"); | 756 beginToken(); // The identifier starts here. |
| 712 next = tokenizeKeywordOrIdentifier(next, false); | 757 next = tokenizeKeywordOrIdentifier(next, false); |
| 713 appendEndGroup(CLOSE_CURLY_BRACKET_INFO, "}", OPEN_CURLY_BRACKET_TOKEN); | 758 beginToken(); // The string interpolation suffix starts here. |
| 714 return next; | 759 return next; |
| 715 } | 760 } |
| 716 | 761 |
| 717 int tokenizeSingleLineRawString(int next, int quoteChar, int start) { | 762 int tokenizeSingleLineRawString(int next, int quoteChar, int start) { |
| 718 next = advance(); | 763 next = advance(); |
| 719 while (next != $EOF) { | 764 while (next != $EOF) { |
| 720 if (next === quoteChar) { | 765 if (next === quoteChar) { |
| 721 appendByteStringToken(STRING_INFO, utf8String(start, 0)); | 766 appendByteStringToken(STRING_INFO, utf8String(start, 0)); |
| 722 return advance(); | 767 return advance(); |
| 723 } else if (next === $LF || next === $CR) { | 768 } else if (next === $LF || next === $CR) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 charOffset); | 825 charOffset); |
| 781 } | 826 } |
| 782 } | 827 } |
| 783 | 828 |
| 784 class MalformedInputException { | 829 class MalformedInputException { |
| 785 final String message; | 830 final String message; |
| 786 final position; | 831 final position; |
| 787 MalformedInputException(this.message, this.position); | 832 MalformedInputException(this.message, this.position); |
| 788 toString() => message; | 833 toString() => message; |
| 789 } | 834 } |
| OLD | NEW |