Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1050)

Side by Side Diff: frog/leg/tools/mini_parser.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/tools/find_file_to_parse.sh ('k') | frog/leg/tree/dartstring.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #library('parser');
6
7 #import('dart:io');
8
9 #import('../../../lib/utf/utf.dart');
10
11 #import('../elements/elements.dart');
12 #import('../scanner/scanner_implementation.dart');
13 #import('../scanner/scannerlib.dart');
14 #import('../tree/tree.dart');
15 #import('../util/characters.dart');
16
17 #source('../diagnostic_listener.dart');
18 #source('../../source.dart');
19 #source('../scanner/byte_array_scanner.dart');
20 #source('../scanner/byte_strings.dart');
21
22 int charCount = 0;
23 Stopwatch stopwatch;
24
25 void main() {
26 filesWithCrashes = [];
27 stopwatch = new Stopwatch();
28 MyOptions options = new MyOptions();
29
30 void printStats() {
31 int kb = (charCount / 1024).round().toInt();
32 String stats =
33 '$classCount classes (${kb}Kb) in ${stopwatch.elapsedInMs()}ms';
34 if (errorCount != 0) {
35 stats += ' with $errorCount errors';
36 }
37 if (options.diet) {
38 print('Diet parsed $stats.');
39 } else {
40 print('Parsed $stats.');
41 }
42 if (filesWithCrashes.length !== 0) {
43 print('The following ${filesWithCrashes.length} files caused a crash:');
44 for (String file in filesWithCrashes) {
45 print(file);
46 }
47 }
48 }
49
50 for (String argument in new Options().arguments) {
51 if (argument == "--diet") {
52 options.diet = true;
53 continue;
54 }
55 if (argument == "--throw") {
56 options.throwOnError = true;
57 continue;
58 }
59 if (argument == "--scan-only") {
60 options.scanOnly = true;
61 continue;
62 }
63 if (argument == "--read-only") {
64 options.readOnly = true;
65 continue;
66 }
67 if (argument == "--ast") {
68 options.buildAst = true;
69 continue;
70 }
71 if (argument == "-") {
72 parseFilesFrom(stdin, options, printStats);
73 return;
74 }
75 stopwatch.start();
76 parseFile(argument, options);
77 stopwatch.stop();
78 }
79
80 printStats();
81 }
82
83 void parseFile(String filename, MyOptions options) {
84 List<int> bytes = read(filename);
85 charCount += bytes.length;
86 if (options.readOnly) return;
87 MySourceFile file = new MySourceFile(filename, bytes);
88 final Listener listener = options.buildAst
89 ? new MyNodeListener(file, options)
90 : new MyListener(file);
91 final Parser parser = options.diet
92 ? new PartialParser(listener)
93 : new Parser(listener);
94 try {
95 Token token = scan(file);
96 if (!options.scanOnly) parser.parseUnit(token);
97 } catch (ParserError ex) {
98 if (options.throwOnError) {
99 throw;
100 } else {
101 print(ex);
102 }
103 } catch (MalformedInputException ex) {
104 // Already diagnosed.
105 } catch (var ex) {
106 print('Error in file: $filename');
107 throw;
108 }
109 if (options.buildAst) {
110 MyNodeListener l = listener;
111 if (!l.nodes.isEmpty()) {
112 String message = 'Stack not empty after parsing';
113 print(formatError(message, l.nodes.head.getBeginToken(),
114 l.nodes.head.getEndToken(), file));
115 throw message;
116 }
117 }
118 }
119
120 Token scan(MySourceFile source) {
121 Scanner scanner = new ByteArrayScanner(source.rawText);
122 try {
123 return scanner.tokenize();
124 } catch (MalformedInputException ex) {
125 if (ex.position is Token) {
126 print(formatError(ex.message, ex.position, ex.position, source));
127 } else {
128 Token fakeToken = new Token(QUESTION_INFO, ex.position);
129 print(formatError(ex.message, fakeToken, fakeToken, source));
130 }
131 throw;
132 }
133 }
134
135 var filesWithCrashes;
136
137 void parseFilesFrom(InputStream input, MyOptions options, Function whenDone) {
138 void readLine(String line) {
139 stopwatch.start();
140 try {
141 parseFile(line, options);
142 } catch (var ex, var trace) {
143 filesWithCrashes.add(line);
144 print(ex);
145 print(trace);
146 }
147 stopwatch.stop();
148 }
149 forEachLine(input, readLine, whenDone);
150 }
151
152 void forEachLine(InputStream input,
153 void lineHandler(String line),
154 void closeHandler()) {
155 StringInputStream stringStream = new StringInputStream(input);
156 stringStream.onLine = () {
157 String line;
158 while ((line = stringStream.readLine()) !== null) {
159 lineHandler(line);
160 }
161 };
162 stringStream.onClosed = closeHandler;
163 }
164
165 List<int> read(String filename) {
166 RandomAccessFile file = new File(filename).openSync();
167 bool threw = true;
168 try {
169 int size = file.lengthSync();
170 List<int> bytes = new ByteArray(size + 1);
171 file.readListSync(bytes, 0, size);
172 bytes[size] = $EOF;
173 threw = false;
174 return bytes;
175 } finally {
176 try {
177 file.closeSync();
178 } catch (var ex) {
179 if (!threw) throw;
180 }
181 }
182 }
183
184 int classCount = 0;
185 int errorCount = 0;
186
187 class MyListener extends Listener {
188 final SourceFile file;
189
190 MyListener(this.file);
191
192 void beginClassDeclaration(Token token) {
193 classCount++;
194 }
195
196 void beginInterface(Token token) {
197 classCount++;
198 }
199
200 void error(String message, Token token) {
201 throw new ParserError(formatError(message, token, token, file));
202 }
203 }
204
205 String formatError(String message, Token beginToken, Token endToken,
206 SourceFile file) {
207 ++errorCount;
208 if (beginToken === null) return '${file.filename}: $message';
209 String tokenString = endToken.toString();
210 int begin = beginToken.charOffset;
211 int end = endToken.charOffset + tokenString.length;
212 return file.getLocationMessage(message, begin, end, true);
213 }
214
215 class MyNodeListener extends NodeListener {
216 MyNodeListener(SourceFile file, MyOptions options)
217 : super(new MyCanceller(file, options), null);
218
219 void beginClassDeclaration(Token token) {
220 classCount++;
221 }
222
223 void beginInterface(Token token) {
224 classCount++;
225 }
226
227 void endClassDeclaration(int interfacesCount, Token beginToken,
228 Token extendsKeyword, Token implementsKeyword,
229 Token endToken) {
230 super.endClassDeclaration(interfacesCount, beginToken,
231 extendsKeyword, implementsKeyword,
232 endToken);
233 ClassNode node = popNode(); // Discard ClassNode and assert the type.
234 }
235
236 void endInterface(int supertypeCount, Token interfaceKeyword,
237 Token extendsKeyword, Token endToken) {
238 super.endInterface(supertypeCount, interfaceKeyword, extendsKeyword,
239 endToken);
240 ClassNode node = popNode(); // Discard ClassNode and assert the type.
241 }
242
243 void endTopLevelFields(int count, Token beginToken, Token endToken) {
244 super.endTopLevelFields(count, beginToken, endToken);
245 VariableDefinitions node = popNode(); // Discard node and assert the type.
246 }
247
248 void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
249 super.endFunctionTypeAlias(typedefKeyword, endToken);
250 Typedef node = popNode(); // Discard Typedef and assert type type.
251 }
252
253 void endLibraryTag(bool hasPrefix, Token beginToken, Token endToken) {
254 super.endLibraryTag(hasPrefix, beginToken, endToken);
255 ScriptTag node = popNode(); // Discard ScriptTag and assert type type.
256 }
257
258 void log(message) {
259 print(message);
260 }
261 }
262
263 class MyCanceller implements DiagnosticListener {
264 final SourceFile file;
265 final MyOptions options;
266
267 MyCanceller(this.file, this.options);
268
269 void log(String message) {}
270
271 void cancel([String reason, node, token, instruction, element]) {
272 Token beginToken;
273 Token endToken;
274 if (token !== null) {
275 beginToken = token;
276 endToken = token;
277 } else if (node !== null) {
278 beginToken = node.getBeginToken();
279 endToken = node.getEndToken();
280 }
281 String message = formatError(reason, beginToken, endToken, file);
282 if (options.throwOnError) throw new ParserError(message);
283 print(message);
284 }
285 }
286
287 class MyOptions {
288 bool diet = false;
289 bool throwOnError = false;
290 bool scanOnly = false;
291 bool readOnly = false;
292 bool buildAst = false;
293 }
294
295 class MySourceFile extends SourceFile {
296 final rawText;
297 var stringText;
298
299 MySourceFile(filename, this.rawText) : super(filename, null);
300
301 String get text() {
302 if (rawText is String) {
303 return rawText;
304 } else {
305 if (stringText === null) {
306 stringText = new String.fromCharCodes(rawText);
307 if (stringText.endsWith('\u0000')) {
308 // Strip trailing NUL used by ByteArrayScanner to signal EOF.
309 stringText = stringText.substring(0, stringText.length - 1);
310 }
311 }
312 return stringText;
313 }
314 }
315
316 set text(String newText) {
317 throw "not supported";
318 }
319 }
320
321 // Hacks to allow sourcing in ../source.dart:
322 var world = const Mock();
323 var options = const Mock();
324 String _GREEN_COLOR = '\u001b[32m';
325 String _RED_COLOR = '\u001b[31m';
326 String _MAGENTA_COLOR = '\u001b[35m';
327 String _NO_COLOR = '\u001b[0m';
328
329 class Mock {
330 const Mock();
331 bool get useColors() => true;
332 internalError(message) { throw message.toString(); }
333 }
OLDNEW
« no previous file with comments | « frog/leg/tools/find_file_to_parse.sh ('k') | frog/leg/tree/dartstring.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698