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 /** | |
|
ahe
2012/06/22 08:42:49
Please add a newline before all the documentation
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 16 * Returns the current char. | |
|
ahe
2012/06/22 08:42:49
No it doesn't :-)
I think the word you're looking
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 17 */ | |
| 15 abstract int peek(); | 18 abstract int peek(); |
| 19 /** | |
| 20 * Appends a fixed token based on whether the current char is [choice] or not. | |
| 21 * If the current char is [choice] a fixed token whose kind and content | |
| 22 * is determined by [yes] is appended, otherwise a fixed token whose kind | |
| 23 * and content is determined by [no] is appended. */ | |
| 16 abstract int select(int choice, PrecedenceInfo yes, PrecedenceInfo no); | 24 abstract int select(int choice, PrecedenceInfo yes, PrecedenceInfo no); |
| 25 /** | |
| 26 * Appends a fixed token whose kind and content is determined by [info]. | |
| 27 */ | |
| 17 abstract void appendPrecedenceToken(PrecedenceInfo info); | 28 abstract void appendPrecedenceToken(PrecedenceInfo info); |
| 29 /** | |
| 30 * Appends a token whose kind is determined by [info] and content is [value]. | |
| 31 */ | |
| 18 abstract void appendStringToken(PrecedenceInfo info, String value); | 32 abstract void appendStringToken(PrecedenceInfo info, String value); |
| 33 /** | |
| 34 * Appends a token whose kind is determined by [info] and content is defined b y | |
|
ahe
2012/06/22 08:42:49
Long line.
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 35 * the SourceString [value]. | |
| 36 */ | |
| 19 abstract void appendByteStringToken(PrecedenceInfo info, T value); | 37 abstract void appendByteStringToken(PrecedenceInfo info, T value); |
| 38 /** | |
| 39 * Appends a keyword token whose kind is determined by [keyword]. | |
| 40 */ | |
| 20 abstract void appendKeywordToken(Keyword keyword); | 41 abstract void appendKeywordToken(Keyword keyword); |
| 21 abstract void appendWhiteSpace(int next); | 42 abstract void appendWhiteSpace(int next); |
| 22 abstract void appendEofToken(); | 43 abstract void appendEofToken(); |
| 44 /** | |
| 45 * Creates an ascii SourceString whose content begins at the source byte | |
| 46 * offset [start] and ends at [offset] bytes from the current byte offset of | |
| 47 * the scanner. I.e. if the current byte offset is 10, [:asciiString(0,-1):] | |
|
ahe
2012/06/22 08:42:49
A tech-writer once recommended that I avoided the
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 48 * creates an ascii SourceString whose content is found at the [0,9[ byte | |
| 49 * interval of the source text. | |
| 50 */ | |
| 23 abstract T asciiString(int start, int offset); | 51 abstract T asciiString(int start, int offset); |
| 24 abstract T utf8String(int start, int offset); | 52 abstract T utf8String(int start, int offset); |
| 25 abstract Token firstToken(); | 53 abstract Token firstToken(); |
| 26 abstract Token previousToken(); | 54 abstract Token previousToken(); |
| 27 abstract void beginToken(); | 55 abstract void beginToken(); |
| 28 abstract void addToCharOffset(int offset); | 56 abstract void addToCharOffset(int offset); |
| 29 abstract int get charOffset(); | 57 abstract int get charOffset(); |
| 30 abstract int get byteOffset(); | 58 abstract int get byteOffset(); |
| 31 abstract void appendBeginGroup(PrecedenceInfo info, String value); | 59 abstract void appendBeginGroup(PrecedenceInfo info, String value); |
| 32 abstract int appendEndGroup(PrecedenceInfo info, String value, int openKind); | 60 abstract int appendEndGroup(PrecedenceInfo info, String value, int openKind); |
| 33 abstract void appendGt(PrecedenceInfo info, String value); | 61 abstract void appendGt(PrecedenceInfo info, String value); |
| 34 abstract void appendGtGt(PrecedenceInfo info, String value); | 62 abstract void appendGtGt(PrecedenceInfo info, String value); |
| 35 abstract void appendGtGtGt(PrecedenceInfo info, String value); | 63 abstract void appendGtGtGt(PrecedenceInfo info, String value); |
| 64 abstract void appendComment(); | |
| 36 | 65 |
| 37 /** | 66 /** |
| 38 * We call this method to discard '<' from the "grouping" stack | 67 * We call this method to discard '<' from the "grouping" stack |
| 39 * (maintained by subclasses). | 68 * (maintained by subclasses). |
| 40 * | 69 * |
| 41 * [PartialParser.skipExpression] relies on the fact that we do not | 70 * [PartialParser.skipExpression] relies on the fact that we do not |
| 42 * create groups for stuff like: | 71 * create groups for stuff like: |
| 43 * [:a = b < c, d = e > f:]. | 72 * [:a = b < c, d = e > f:]. |
| 44 * | 73 * |
| 45 * In other words, this method is called when the scanner recognizes | 74 * In other words, this method is called when the scanner recognizes |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 return advance(); | 564 return advance(); |
| 536 } else { | 565 } else { |
| 537 appendPrecedenceToken(SLASH_INFO); | 566 appendPrecedenceToken(SLASH_INFO); |
| 538 return next; | 567 return next; |
| 539 } | 568 } |
| 540 } | 569 } |
| 541 | 570 |
| 542 int tokenizeSingleLineComment(int next) { | 571 int tokenizeSingleLineComment(int next) { |
| 543 while (true) { | 572 while (true) { |
| 544 next = advance(); | 573 next = advance(); |
| 545 if ($LF === next || $CR === next || $EOF === next) { | 574 if ($LF === next || $CR === next || $EOF === next) { |
|
ahe
2012/06/22 08:42:49
Should we include DOS line endings?
Johnni Winther
2012/06/22 09:55:52
The terminating character is not included in the s
| |
| 575 appendComment(); | |
| 546 return next; | 576 return next; |
| 547 } | 577 } |
| 548 } | 578 } |
| 549 } | 579 } |
| 550 | 580 |
| 551 int tokenizeMultiLineComment(int next) { | 581 int tokenizeMultiLineComment(int next) { |
| 552 int nesting = 1; | 582 int nesting = 1; |
| 553 next = advance(); | 583 next = advance(); |
| 554 while (true) { | 584 while (true) { |
| 555 if ($EOF === next) { | 585 if ($EOF === next) { |
| 556 // TODO(ahe): Report error. | 586 // TODO(ahe): Report error. |
| 557 return next; | 587 return next; |
| 558 } else if ($STAR === next) { | 588 } else if ($STAR === next) { |
| 559 next = advance(); | 589 next = advance(); |
| 560 if ($SLASH === next) { | 590 if ($SLASH === next) { |
| 561 --nesting; | 591 --nesting; |
| 562 if (0 === nesting) { | 592 if (0 === nesting) { |
| 563 return advance(); | 593 next = advance(); |
| 594 appendComment(); | |
| 595 return next; | |
| 564 } else { | 596 } else { |
| 565 next = advance(); | 597 next = advance(); |
| 566 } | 598 } |
| 567 } | 599 } |
| 568 } else if ($SLASH === next) { | 600 } else if ($SLASH === next) { |
| 569 next = advance(); | 601 next = advance(); |
| 570 if ($STAR === next) { | 602 if ($STAR === next) { |
| 571 next = advance(); | 603 next = advance(); |
| 572 ++nesting; | 604 ++nesting; |
| 573 } | 605 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 throw new MalformedInputException("unterminated string literal", | 711 throw new MalformedInputException("unterminated string literal", |
| 680 charOffset); | 712 charOffset); |
| 681 } | 713 } |
| 682 next = advance(); | 714 next = advance(); |
| 683 } | 715 } |
| 684 appendByteStringToken(STRING_INFO, utf8String(start, 0)); | 716 appendByteStringToken(STRING_INFO, utf8String(start, 0)); |
| 685 return advance(); | 717 return advance(); |
| 686 } | 718 } |
| 687 | 719 |
| 688 int tokenizeStringInterpolation(int start) { | 720 int tokenizeStringInterpolation(int start) { |
| 689 beginToken(); | 721 appendByteStringToken(STRING_INFO, utf8String(start, -1)); |
| 722 beginToken(); // $ starts here | |
|
ahe
2012/06/22 08:42:49
Not a proper sentence. A proper sentence starts wi
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 690 int next = advance(); | 723 int next = advance(); |
| 691 if (next === $OPEN_CURLY_BRACKET) { | 724 if (next === $OPEN_CURLY_BRACKET) { |
| 692 return tokenizeInterpolatedExpression(next, start); | 725 return tokenizeInterpolatedExpression(next, start); |
| 693 } else { | 726 } else { |
| 694 return tokenizeInterpolatedIdentifier(next, start); | 727 return tokenizeInterpolatedIdentifier(next, start); |
| 695 } | 728 } |
| 696 } | 729 } |
| 697 | 730 |
| 698 int tokenizeInterpolatedExpression(int next, int start) { | 731 int tokenizeInterpolatedExpression(int next, int start) { |
| 699 appendByteStringToken(STRING_INFO, utf8String(start, -2)); | |
| 700 appendBeginGroup(STRING_INTERPOLATION_INFO, "\${"); | 732 appendBeginGroup(STRING_INTERPOLATION_INFO, "\${"); |
| 733 beginToken(); // expression starts here | |
|
ahe
2012/06/22 08:42:49
Not proper sentence.
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 701 next = advance(); | 734 next = advance(); |
| 702 while (next !== $EOF && next !== $STX) { | 735 while (next !== $EOF && next !== $STX) { |
| 703 next = bigSwitch(next); | 736 next = bigSwitch(next); |
| 704 } | 737 } |
| 705 if (next === $EOF) return next; | 738 if (next === $EOF) return next; |
| 706 return advance(); | 739 next = advance(); |
| 740 beginToken(); // string interpolation suffix starts here | |
|
ahe
2012/06/22 08:42:49
Ditto.
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 741 return next; | |
| 707 } | 742 } |
| 708 | 743 |
| 709 int tokenizeInterpolatedIdentifier(int next, int start) { | 744 int tokenizeInterpolatedIdentifier(int next, int start) { |
| 710 appendByteStringToken(STRING_INFO, utf8String(start, -2)); | 745 appendBeginGroup(STRING_INTERPOLATION_INFO, "\$"); |
| 711 appendBeginGroup(STRING_INTERPOLATION_INFO, "\${"); | 746 beginToken(); // identifier starts here |
|
ahe
2012/06/22 08:42:49
Ditto.
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 712 next = tokenizeKeywordOrIdentifier(next, false); | 747 next = tokenizeKeywordOrIdentifier(next, false); |
| 713 appendEndGroup(CLOSE_CURLY_BRACKET_INFO, "}", OPEN_CURLY_BRACKET_TOKEN); | 748 beginToken(); // string interpolation suffix starts here |
|
ahe
2012/06/22 08:42:49
Ditto.
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 749 appendEndGroup(CLOSE_CURLY_BRACKET_INFO, "", OPEN_CURLY_BRACKET_TOKEN); | |
|
ahe
2012/06/22 08:42:49
This is not a CLOSE_CURLE_BRACKET.
Johnni Winther
2012/06/22 10:23:10
Done.
| |
| 714 return next; | 750 return next; |
| 715 } | 751 } |
| 716 | 752 |
| 717 int tokenizeSingleLineRawString(int next, int quoteChar, int start) { | 753 int tokenizeSingleLineRawString(int next, int quoteChar, int start) { |
| 718 next = advance(); | 754 next = advance(); |
| 719 while (next != $EOF) { | 755 while (next != $EOF) { |
| 720 if (next === quoteChar) { | 756 if (next === quoteChar) { |
| 721 appendByteStringToken(STRING_INFO, utf8String(start, 0)); | 757 appendByteStringToken(STRING_INFO, utf8String(start, 0)); |
| 722 return advance(); | 758 return advance(); |
| 723 } else if (next === $LF || next === $CR) { | 759 } else if (next === $LF || next === $CR) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 charOffset); | 816 charOffset); |
| 781 } | 817 } |
| 782 } | 818 } |
| 783 | 819 |
| 784 class MalformedInputException { | 820 class MalformedInputException { |
| 785 final String message; | 821 final String message; |
| 786 final position; | 822 final position; |
| 787 MalformedInputException(this.message, this.position); | 823 MalformedInputException(this.message, this.position); |
| 788 toString() => message; | 824 toString() => message; |
| 789 } | 825 } |
| OLD | NEW |