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 /** | 5 /** |
| 6 * An event generating parser of Dart programs. This parser expects | 6 * An event generating parser of Dart programs. This parser expects |
| 7 * all tokens in a linked list (aka a token stream). | 7 * all tokens in a linked list (aka a token stream). |
| 8 * | 8 * |
| 9 * The class [Scanner] is used to generate a token stream. See the | 9 * The class [Scanner] is used to generate a token stream. See the |
| 10 * file scanner.dart. | 10 * file scanner.dart. |
| 11 * | 11 * |
| 12 * Subclasses of the class [Listener] are used to listen to events. | 12 * Subclasses of the class [Listener] are used to listen to events. |
| 13 * | |
| 14 * Most methods of this class belong in one of two major categories: | |
| 15 * parse metods and peek methods. Parse methods all have the prefix | |
| 16 * parse, and peek methods all have the prefix peek. | |
| 17 * | |
| 18 * Parse methods generate events (by calling methods on [listener]) | |
| 19 * and return the next token to parse. Peek methods do not generate | |
| 20 * events (except for errors) and may return null. | |
| 21 * | |
| 22 * Parse methods are generally named parseGrammarProductionSuffix. The | |
| 23 * suffix can be one of "opt", or "star". "opt" means zero or one | |
| 24 * matches, "star" means zero or more matches. For example, | |
|
ngeoffray
2012/08/21 10:51:21
zero or one match
ahe
2012/08/21 10:55:37
I don't think that is correct.
"star" means i rep
| |
| 25 * [parseMetadataStar] corresponds to this grammar snippet: [: | |
| 26 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. | |
| 13 */ | 27 */ |
| 14 class Parser { | 28 class Parser { |
| 15 final Listener listener; | 29 final Listener listener; |
| 16 bool mayParseFunctionExpressions = true; | 30 bool mayParseFunctionExpressions = true; |
| 17 | 31 |
| 18 Parser(Listener this.listener); | 32 Parser(this.listener); |
| 19 | 33 |
| 20 void parseUnit(Token token) { | 34 void parseUnit(Token token) { |
| 21 while (token.kind !== EOF_TOKEN) { | 35 while (token.kind !== EOF_TOKEN) { |
| 22 token = parseTopLevelDeclaration(token); | 36 token = parseTopLevelDeclaration(token); |
| 23 } | 37 } |
| 24 } | 38 } |
| 25 | 39 |
| 26 Token parseTopLevelDeclaration(Token token) { | 40 Token parseTopLevelDeclaration(Token token) { |
| 41 token = parseMetadataStar(token); | |
| 27 final String value = token.stringValue; | 42 final String value = token.stringValue; |
| 28 if (value === 'interface') { | 43 if (value === 'interface') { |
| 29 return parseInterface(token); | 44 return parseInterface(token); |
| 30 } else if ((value === 'abstract') || (value === 'class')) { | 45 } else if ((value === 'abstract') || (value === 'class')) { |
| 31 return parseClass(token); | 46 return parseClass(token); |
| 32 } else if (value === 'typedef') { | 47 } else if (value === 'typedef') { |
| 33 return parseNamedFunctionAlias(token); | 48 return parseNamedFunctionAlias(token); |
| 34 } else if (value === '#') { | 49 } else if (value === '#') { |
| 35 return parseScriptTags(token); | 50 return parseScriptTags(token); |
| 36 } else { | 51 } else { |
| 37 return parseTopLevelMember(token); | 52 return parseTopLevelMember(token); |
| 38 } | 53 } |
| 39 } | 54 } |
| 40 | 55 |
| 56 Token parseMetadataStar(Token token) { | |
| 57 while (optional('@', token)) { | |
| 58 token = parseMetadata(token); | |
| 59 } | |
| 60 return token; | |
| 61 } | |
| 62 | |
| 63 Token parseMetadata(Token token) { | |
| 64 listener.beginMetadata(token); | |
| 65 Token atToken = token; | |
| 66 assert(optional('@', token)); | |
| 67 token = parseIdentifier(token.next); | |
| 68 token = parseQualifiedRestOpt(token); | |
| 69 token = parseArgumentsOpt(token); | |
| 70 listener.endMetadata(atToken, token); | |
| 71 return token; | |
| 72 } | |
| 73 | |
| 41 Token parseInterface(Token token) { | 74 Token parseInterface(Token token) { |
| 42 Token interfaceKeyword = token; | 75 Token interfaceKeyword = token; |
| 43 listener.beginInterface(token); | 76 listener.beginInterface(token); |
| 44 token = parseIdentifier(token.next); | 77 token = parseIdentifier(token.next); |
| 45 token = parseTypeVariablesOpt(token); | 78 token = parseTypeVariablesOpt(token); |
| 46 int supertypeCount = 0; | 79 int supertypeCount = 0; |
| 47 Token extendsKeyword = null; | 80 Token extendsKeyword = null; |
| 48 if (optional('extends', token)) { | 81 if (optional('extends', token)) { |
| 49 extendsKeyword = token; | 82 extendsKeyword = token; |
| 50 do { | 83 do { |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 final Token peek = peekAfterExpectedType(token); | 612 final Token peek = peekAfterExpectedType(token); |
| 580 if (isGetOrSet(peek) && isIdentifier(peek.next)) { | 613 if (isGetOrSet(peek) && isIdentifier(peek.next)) { |
| 581 // type? get identifier | 614 // type? get identifier |
| 582 return peek; | 615 return peek; |
| 583 } | 616 } |
| 584 } | 617 } |
| 585 return null; | 618 return null; |
| 586 } | 619 } |
| 587 | 620 |
| 588 Token parseMember(Token token) { | 621 Token parseMember(Token token) { |
| 622 token = parseMetadataStar(token); | |
| 589 String value = token.stringValue; | 623 String value = token.stringValue; |
| 590 if (value === 'factory' || | 624 if (value === 'factory' || |
| 591 (value === 'external' && optional('factory', token.next))) { | 625 (value === 'external' && optional('factory', token.next))) { |
| 592 return parseFactoryMethod(token); | 626 return parseFactoryMethod(token); |
| 593 } | 627 } |
| 594 Token start = token; | 628 Token start = token; |
| 595 listener.beginMember(token); | 629 listener.beginMember(token); |
| 596 token = parseModifiers(token); | 630 token = parseModifiers(token); |
| 597 Token getOrSet = findGetOrSet(token); | 631 Token getOrSet = findGetOrSet(token); |
| 598 if (token === getOrSet) token = token.next; | 632 if (token === getOrSet) token = token.next; |
| (...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1789 } | 1823 } |
| 1790 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1824 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1791 return expectSemicolon(token); | 1825 return expectSemicolon(token); |
| 1792 } | 1826 } |
| 1793 | 1827 |
| 1794 Token parseEmptyStatement(Token token) { | 1828 Token parseEmptyStatement(Token token) { |
| 1795 listener.handleEmptyStatement(token); | 1829 listener.handleEmptyStatement(token); |
| 1796 return expectSemicolon(token); | 1830 return expectSemicolon(token); |
| 1797 } | 1831 } |
| 1798 } | 1832 } |
| OLD | NEW |