| Index: frog/leg/tools/mini_parser.dart
|
| ===================================================================
|
| --- frog/leg/tools/mini_parser.dart (revision 5925)
|
| +++ frog/leg/tools/mini_parser.dart (working copy)
|
| @@ -1,333 +0,0 @@
|
| -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -#library('parser');
|
| -
|
| -#import('dart:io');
|
| -
|
| -#import('../../../lib/utf/utf.dart');
|
| -
|
| -#import('../elements/elements.dart');
|
| -#import('../scanner/scanner_implementation.dart');
|
| -#import('../scanner/scannerlib.dart');
|
| -#import('../tree/tree.dart');
|
| -#import('../util/characters.dart');
|
| -
|
| -#source('../diagnostic_listener.dart');
|
| -#source('../../source.dart');
|
| -#source('../scanner/byte_array_scanner.dart');
|
| -#source('../scanner/byte_strings.dart');
|
| -
|
| -int charCount = 0;
|
| -Stopwatch stopwatch;
|
| -
|
| -void main() {
|
| - filesWithCrashes = [];
|
| - stopwatch = new Stopwatch();
|
| - MyOptions options = new MyOptions();
|
| -
|
| - void printStats() {
|
| - int kb = (charCount / 1024).round().toInt();
|
| - String stats =
|
| - '$classCount classes (${kb}Kb) in ${stopwatch.elapsedInMs()}ms';
|
| - if (errorCount != 0) {
|
| - stats += ' with $errorCount errors';
|
| - }
|
| - if (options.diet) {
|
| - print('Diet parsed $stats.');
|
| - } else {
|
| - print('Parsed $stats.');
|
| - }
|
| - if (filesWithCrashes.length !== 0) {
|
| - print('The following ${filesWithCrashes.length} files caused a crash:');
|
| - for (String file in filesWithCrashes) {
|
| - print(file);
|
| - }
|
| - }
|
| - }
|
| -
|
| - for (String argument in new Options().arguments) {
|
| - if (argument == "--diet") {
|
| - options.diet = true;
|
| - continue;
|
| - }
|
| - if (argument == "--throw") {
|
| - options.throwOnError = true;
|
| - continue;
|
| - }
|
| - if (argument == "--scan-only") {
|
| - options.scanOnly = true;
|
| - continue;
|
| - }
|
| - if (argument == "--read-only") {
|
| - options.readOnly = true;
|
| - continue;
|
| - }
|
| - if (argument == "--ast") {
|
| - options.buildAst = true;
|
| - continue;
|
| - }
|
| - if (argument == "-") {
|
| - parseFilesFrom(stdin, options, printStats);
|
| - return;
|
| - }
|
| - stopwatch.start();
|
| - parseFile(argument, options);
|
| - stopwatch.stop();
|
| - }
|
| -
|
| - printStats();
|
| -}
|
| -
|
| -void parseFile(String filename, MyOptions options) {
|
| - List<int> bytes = read(filename);
|
| - charCount += bytes.length;
|
| - if (options.readOnly) return;
|
| - MySourceFile file = new MySourceFile(filename, bytes);
|
| - final Listener listener = options.buildAst
|
| - ? new MyNodeListener(file, options)
|
| - : new MyListener(file);
|
| - final Parser parser = options.diet
|
| - ? new PartialParser(listener)
|
| - : new Parser(listener);
|
| - try {
|
| - Token token = scan(file);
|
| - if (!options.scanOnly) parser.parseUnit(token);
|
| - } catch (ParserError ex) {
|
| - if (options.throwOnError) {
|
| - throw;
|
| - } else {
|
| - print(ex);
|
| - }
|
| - } catch (MalformedInputException ex) {
|
| - // Already diagnosed.
|
| - } catch (var ex) {
|
| - print('Error in file: $filename');
|
| - throw;
|
| - }
|
| - if (options.buildAst) {
|
| - MyNodeListener l = listener;
|
| - if (!l.nodes.isEmpty()) {
|
| - String message = 'Stack not empty after parsing';
|
| - print(formatError(message, l.nodes.head.getBeginToken(),
|
| - l.nodes.head.getEndToken(), file));
|
| - throw message;
|
| - }
|
| - }
|
| -}
|
| -
|
| -Token scan(MySourceFile source) {
|
| - Scanner scanner = new ByteArrayScanner(source.rawText);
|
| - try {
|
| - return scanner.tokenize();
|
| - } catch (MalformedInputException ex) {
|
| - if (ex.position is Token) {
|
| - print(formatError(ex.message, ex.position, ex.position, source));
|
| - } else {
|
| - Token fakeToken = new Token(QUESTION_INFO, ex.position);
|
| - print(formatError(ex.message, fakeToken, fakeToken, source));
|
| - }
|
| - throw;
|
| - }
|
| -}
|
| -
|
| -var filesWithCrashes;
|
| -
|
| -void parseFilesFrom(InputStream input, MyOptions options, Function whenDone) {
|
| - void readLine(String line) {
|
| - stopwatch.start();
|
| - try {
|
| - parseFile(line, options);
|
| - } catch (var ex, var trace) {
|
| - filesWithCrashes.add(line);
|
| - print(ex);
|
| - print(trace);
|
| - }
|
| - stopwatch.stop();
|
| - }
|
| - forEachLine(input, readLine, whenDone);
|
| -}
|
| -
|
| -void forEachLine(InputStream input,
|
| - void lineHandler(String line),
|
| - void closeHandler()) {
|
| - StringInputStream stringStream = new StringInputStream(input);
|
| - stringStream.onLine = () {
|
| - String line;
|
| - while ((line = stringStream.readLine()) !== null) {
|
| - lineHandler(line);
|
| - }
|
| - };
|
| - stringStream.onClosed = closeHandler;
|
| -}
|
| -
|
| -List<int> read(String filename) {
|
| - RandomAccessFile file = new File(filename).openSync();
|
| - bool threw = true;
|
| - try {
|
| - int size = file.lengthSync();
|
| - List<int> bytes = new ByteArray(size + 1);
|
| - file.readListSync(bytes, 0, size);
|
| - bytes[size] = $EOF;
|
| - threw = false;
|
| - return bytes;
|
| - } finally {
|
| - try {
|
| - file.closeSync();
|
| - } catch (var ex) {
|
| - if (!threw) throw;
|
| - }
|
| - }
|
| -}
|
| -
|
| -int classCount = 0;
|
| -int errorCount = 0;
|
| -
|
| -class MyListener extends Listener {
|
| - final SourceFile file;
|
| -
|
| - MyListener(this.file);
|
| -
|
| - void beginClassDeclaration(Token token) {
|
| - classCount++;
|
| - }
|
| -
|
| - void beginInterface(Token token) {
|
| - classCount++;
|
| - }
|
| -
|
| - void error(String message, Token token) {
|
| - throw new ParserError(formatError(message, token, token, file));
|
| - }
|
| -}
|
| -
|
| -String formatError(String message, Token beginToken, Token endToken,
|
| - SourceFile file) {
|
| - ++errorCount;
|
| - if (beginToken === null) return '${file.filename}: $message';
|
| - String tokenString = endToken.toString();
|
| - int begin = beginToken.charOffset;
|
| - int end = endToken.charOffset + tokenString.length;
|
| - return file.getLocationMessage(message, begin, end, true);
|
| -}
|
| -
|
| -class MyNodeListener extends NodeListener {
|
| - MyNodeListener(SourceFile file, MyOptions options)
|
| - : super(new MyCanceller(file, options), null);
|
| -
|
| - void beginClassDeclaration(Token token) {
|
| - classCount++;
|
| - }
|
| -
|
| - void beginInterface(Token token) {
|
| - classCount++;
|
| - }
|
| -
|
| - void endClassDeclaration(int interfacesCount, Token beginToken,
|
| - Token extendsKeyword, Token implementsKeyword,
|
| - Token endToken) {
|
| - super.endClassDeclaration(interfacesCount, beginToken,
|
| - extendsKeyword, implementsKeyword,
|
| - endToken);
|
| - ClassNode node = popNode(); // Discard ClassNode and assert the type.
|
| - }
|
| -
|
| - void endInterface(int supertypeCount, Token interfaceKeyword,
|
| - Token extendsKeyword, Token endToken) {
|
| - super.endInterface(supertypeCount, interfaceKeyword, extendsKeyword,
|
| - endToken);
|
| - ClassNode node = popNode(); // Discard ClassNode and assert the type.
|
| - }
|
| -
|
| - void endTopLevelFields(int count, Token beginToken, Token endToken) {
|
| - super.endTopLevelFields(count, beginToken, endToken);
|
| - VariableDefinitions node = popNode(); // Discard node and assert the type.
|
| - }
|
| -
|
| - void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
|
| - super.endFunctionTypeAlias(typedefKeyword, endToken);
|
| - Typedef node = popNode(); // Discard Typedef and assert type type.
|
| - }
|
| -
|
| - void endLibraryTag(bool hasPrefix, Token beginToken, Token endToken) {
|
| - super.endLibraryTag(hasPrefix, beginToken, endToken);
|
| - ScriptTag node = popNode(); // Discard ScriptTag and assert type type.
|
| - }
|
| -
|
| - void log(message) {
|
| - print(message);
|
| - }
|
| -}
|
| -
|
| -class MyCanceller implements DiagnosticListener {
|
| - final SourceFile file;
|
| - final MyOptions options;
|
| -
|
| - MyCanceller(this.file, this.options);
|
| -
|
| - void log(String message) {}
|
| -
|
| - void cancel([String reason, node, token, instruction, element]) {
|
| - Token beginToken;
|
| - Token endToken;
|
| - if (token !== null) {
|
| - beginToken = token;
|
| - endToken = token;
|
| - } else if (node !== null) {
|
| - beginToken = node.getBeginToken();
|
| - endToken = node.getEndToken();
|
| - }
|
| - String message = formatError(reason, beginToken, endToken, file);
|
| - if (options.throwOnError) throw new ParserError(message);
|
| - print(message);
|
| - }
|
| -}
|
| -
|
| -class MyOptions {
|
| - bool diet = false;
|
| - bool throwOnError = false;
|
| - bool scanOnly = false;
|
| - bool readOnly = false;
|
| - bool buildAst = false;
|
| -}
|
| -
|
| -class MySourceFile extends SourceFile {
|
| - final rawText;
|
| - var stringText;
|
| -
|
| - MySourceFile(filename, this.rawText) : super(filename, null);
|
| -
|
| - String get text() {
|
| - if (rawText is String) {
|
| - return rawText;
|
| - } else {
|
| - if (stringText === null) {
|
| - stringText = new String.fromCharCodes(rawText);
|
| - if (stringText.endsWith('\u0000')) {
|
| - // Strip trailing NUL used by ByteArrayScanner to signal EOF.
|
| - stringText = stringText.substring(0, stringText.length - 1);
|
| - }
|
| - }
|
| - return stringText;
|
| - }
|
| - }
|
| -
|
| - set text(String newText) {
|
| - throw "not supported";
|
| - }
|
| -}
|
| -
|
| -// Hacks to allow sourcing in ../source.dart:
|
| -var world = const Mock();
|
| -var options = const Mock();
|
| -String _GREEN_COLOR = '\u001b[32m';
|
| -String _RED_COLOR = '\u001b[31m';
|
| -String _MAGENTA_COLOR = '\u001b[35m';
|
| -String _NO_COLOR = '\u001b[0m';
|
| -
|
| -class Mock {
|
| - const Mock();
|
| - bool get useColors() => true;
|
| - internalError(message) { throw message.toString(); }
|
| -}
|
|
|