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 library dart2js.parser; | 5 library dart2js.parser; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../tokens/keyword.dart' show | 8 import '../tokens/keyword.dart' show |
9 Keyword; | 9 Keyword; |
10 import '../tokens/precedence.dart' show | 10 import '../tokens/precedence.dart' show |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 final String type; | 65 final String type; |
66 const FormalParameterType(this.type); | 66 const FormalParameterType(this.type); |
67 bool get isRequired => this == REQUIRED; | 67 bool get isRequired => this == REQUIRED; |
68 bool get isPositional => this == POSITIONAL; | 68 bool get isPositional => this == POSITIONAL; |
69 bool get isNamed => this == NAMED; | 69 bool get isNamed => this == NAMED; |
70 static final REQUIRED = const FormalParameterType('required'); | 70 static final REQUIRED = const FormalParameterType('required'); |
71 static final POSITIONAL = const FormalParameterType('positional'); | 71 static final POSITIONAL = const FormalParameterType('positional'); |
72 static final NAMED = const FormalParameterType('named'); | 72 static final NAMED = const FormalParameterType('named'); |
73 } | 73 } |
74 | 74 |
75 /// Options used for parsing. | |
76 /// | |
77 /// Use this to conditionally support certain constructs, e.g., | |
78 /// experimental ones. | |
79 class ParserOptions { | |
80 final bool enableConditionalDirectives; | |
81 const ParserOptions({this.enableConditionalDirectives: false}); | |
Johnni Winther
2016/03/11 13:43:39
Nit: Add an empty line before the constructor.
eernst
2016/03/21 13:03:34
Done.
| |
82 } | |
83 | |
75 /** | 84 /** |
76 * An event generating parser of Dart programs. This parser expects | 85 * An event generating parser of Dart programs. This parser expects |
77 * all tokens in a linked list (aka a token stream). | 86 * all tokens in a linked list (aka a token stream). |
78 * | 87 * |
79 * The class [Scanner] is used to generate a token stream. See the | 88 * The class [Scanner] is used to generate a token stream. See the |
80 * file scanner.dart. | 89 * file scanner.dart. |
81 * | 90 * |
82 * Subclasses of the class [Listener] are used to listen to events. | 91 * Subclasses of the class [Listener] are used to listen to events. |
83 * | 92 * |
84 * Most methods of this class belong in one of two major categories: | 93 * Most methods of this class belong in one of two major categories: |
85 * parse metods and peek methods. Parse methods all have the prefix | 94 * parse metods and peek methods. Parse methods all have the prefix |
86 * parse, and peek methods all have the prefix peek. | 95 * parse, and peek methods all have the prefix peek. |
87 * | 96 * |
88 * Parse methods generate events (by calling methods on [listener]) | 97 * Parse methods generate events (by calling methods on [listener]) |
89 * and return the next token to parse. Peek methods do not generate | 98 * and return the next token to parse. Peek methods do not generate |
90 * events (except for errors) and may return null. | 99 * events (except for errors) and may return null. |
91 * | 100 * |
92 * Parse methods are generally named parseGrammarProductionSuffix. The | 101 * Parse methods are generally named parseGrammarProductionSuffix. The |
93 * suffix can be one of "opt", or "star". "opt" means zero or one | 102 * suffix can be one of "opt", or "star". "opt" means zero or one |
94 * matches, "star" means zero or more matches. For example, | 103 * matches, "star" means zero or more matches. For example, |
95 * [parseMetadataStar] corresponds to this grammar snippet: [: | 104 * [parseMetadataStar] corresponds to this grammar snippet: [: |
96 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. | 105 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. |
97 */ | 106 */ |
98 class Parser { | 107 class Parser { |
99 final Listener listener; | 108 final Listener listener; |
109 final ParserOptions parserOptions; | |
100 bool mayParseFunctionExpressions = true; | 110 bool mayParseFunctionExpressions = true; |
101 final bool enableConditionalDirectives; | |
102 bool asyncAwaitKeywordsEnabled; | 111 bool asyncAwaitKeywordsEnabled; |
103 | 112 |
104 Parser(this.listener, | 113 Parser(this.listener, this.parserOptions, |
105 {this.enableConditionalDirectives: false, | 114 {this.asyncAwaitKeywordsEnabled: false}); |
106 this.asyncAwaitKeywordsEnabled: false}); | |
107 | 115 |
108 Token parseUnit(Token token) { | 116 Token parseUnit(Token token) { |
109 listener.beginCompilationUnit(token); | 117 listener.beginCompilationUnit(token); |
110 int count = 0; | 118 int count = 0; |
111 while (!identical(token.kind, EOF_TOKEN)) { | 119 while (!identical(token.kind, EOF_TOKEN)) { |
112 token = parseTopLevelDeclaration(token); | 120 token = parseTopLevelDeclaration(token); |
113 listener.endTopLevelDeclaration(token); | 121 listener.endTopLevelDeclaration(token); |
114 count++; | 122 count++; |
115 } | 123 } |
116 listener.endCompilationUnit(count, token); | 124 listener.endCompilationUnit(count, token); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 Token semicolon = token; | 181 Token semicolon = token; |
174 token = expect(';', token); | 182 token = expect(';', token); |
175 listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon); | 183 listener.endImport(importKeyword, deferredKeyword, asKeyword, semicolon); |
176 return token; | 184 return token; |
177 } | 185 } |
178 | 186 |
179 /// if (test) uri | 187 /// if (test) uri |
180 Token parseConditionalUris(Token token) { | 188 Token parseConditionalUris(Token token) { |
181 listener.beginConditionalUris(token); | 189 listener.beginConditionalUris(token); |
182 int count = 0; | 190 int count = 0; |
183 if (enableConditionalDirectives) { | 191 if (parserOptions.enableConditionalDirectives) { |
184 while (optional('if', token)) { | 192 while (optional('if', token)) { |
185 count++; | 193 count++; |
186 token = parseConditionalUri(token); | 194 token = parseConditionalUri(token); |
187 } | 195 } |
188 } | 196 } |
189 listener.endConditionalUris(count); | 197 listener.endConditionalUris(count); |
190 return token; | 198 return token; |
191 } | 199 } |
192 | 200 |
193 Token parseConditionalUri(Token token) { | 201 Token parseConditionalUri(Token token) { |
(...skipping 2584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2778 } | 2786 } |
2779 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 2787 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
2780 return expectSemicolon(token); | 2788 return expectSemicolon(token); |
2781 } | 2789 } |
2782 | 2790 |
2783 Token parseEmptyStatement(Token token) { | 2791 Token parseEmptyStatement(Token token) { |
2784 listener.handleEmptyStatement(token); | 2792 listener.handleEmptyStatement(token); |
2785 return expectSemicolon(token); | 2793 return expectSemicolon(token); |
2786 } | 2794 } |
2787 } | 2795 } |
OLD | NEW |