diff --git a/tools/spec_parse.py b/tools/spec_parse.py index 79ba3069e29..ba87ff84525 100755 --- a/tools/spec_parse.py +++ b/tools/spec_parse.py @@ -4,14 +4,14 @@ # 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. -# This script runs the parser which is generated using ANTLR 3 from +# This script runs the parser which is generated using ANTLR 4 from # docs/language/Dart.g. It relies on a certain environment and is hence # usable locally where this environment can be obtained, but it may not be # possible to run it, e.g., on build bots. The requirements are as follows: # # - `make parser` in spec_parser has been executed successfully. # - A suitable JVM is in the PATH and may be executed as 'java'. -# - the ANTLR3 jar is available as /usr/share/java/antlr3-runtime.jar. +# - the ANTLR3 jar is available as /usr/share/java/antlr4-runtime.jar. import os import string @@ -32,7 +32,7 @@ def Main(): tools_dir = os.path.dirname(os.path.realpath(__file__)) spec_parser_dir = os.path.join(tools_dir, 'spec_parser') spec_parser_file = os.path.join(spec_parser_dir, 'SpecParser.class') - antlr_jar = '/usr/share/java/antlr3-runtime.jar' + antlr_jar = '/usr/share/java/antlr4-runtime.jar' class_path = string.join([spec_parser_dir, antlr_jar], ':') command = ['java', '-cp', class_path, 'SpecParser'] + args diff --git a/tools/spec_parser/.gitignore b/tools/spec_parser/.gitignore index 58106522710..8f983c787ee 100644 --- a/tools/spec_parser/.gitignore +++ b/tools/spec_parser/.gitignore @@ -1,5 +1,6 @@ *Lexer.java *Parser.java +*Listener.java *.tokens *.class *.dot diff --git a/docs/language/Dart.g b/tools/spec_parser/Dart.g similarity index 78% rename from docs/language/Dart.g rename to tools/spec_parser/Dart.g index f586c96fb64..099964f583d 100644 --- a/docs/language/Dart.g +++ b/tools/spec_parser/Dart.g @@ -43,29 +43,6 @@ import java.util.Stack; return !errorHasOccurred; } - /// Produce grammar debugging friendly output, as described in 'The - /// Definitive ANTLR Reference', p247. - public String getErrorMessage(RecognitionException e, String[] tokenNames) { - List stack = getRuleInvocationStack(e, this.getClass().getName()); - String msg = null; - if (e instanceof NoViableAltException) { - NoViableAltException nvae = (NoViableAltException)e; - msg = "no viable alt; token=" + e.token + - " (decision=" + nvae.decisionNumber + - " state " + nvae.stateNumber + ")" + - " decision=<<" + nvae.grammarDecisionDescription + ">>"; - } - else { - msg = super.getErrorMessage(e, tokenNames); - } - if (!errorHasOccurred) prepareForErrors(); - return stack + " " + msg; - } - - public String getTokenErrorDisplay(Token t) { - return t.toString(); - } - // Enable the parser to treat ASYNC/AWAIT/YIELD as keywords in the body of an // `async`, `async*`, or `sync*` function. Access via methods below. private Stack asyncEtcAreKeywords = new Stack(); @@ -89,20 +66,6 @@ import java.util.Stack; } return false; } - - // Debugging support methods. - void dp(int indent, String method, String sep) { - for (int i = 0; i < indent; i++) { - System.out.print(" "); - } - System.out.println(method + sep + " " + input.LT(1) + " " + state.failed); - } - - void dpBegin(int indent, String method) { dp(indent, method, ":"); } - void dpEnd(int indent, String method) { dp(indent, method, " END:"); } - void dpCall(int indent, String method) { dp(indent, method, "?"); } - void dpCalled(int indent, String method) { dp(indent, method, ".."); } - void dpResult(int indent, String method) { dp(indent, method, "!"); } } @lexer::members{ @@ -112,13 +75,6 @@ import java.util.Stack; public static final int BRACE_THREE_SINGLE = 4; public static final int BRACE_THREE_DOUBLE = 5; - /// This override ensures that lexer errors are recognized as errors, - /// but does not change the format of the reported error. - public String getErrorMessage(RecognitionException e, String[] tokenNames) { - if (!DartParser.errorHasOccurred) DartParser.prepareForErrors(); - return super.getErrorMessage(e, tokenNames); - } - // Enable the parser to handle string interpolations via brace matching. // The top of the `braceLevels` stack describes the most recent unmatched // '{'. This is needed in order to enable/disable certain lexer rules. @@ -171,9 +127,9 @@ import java.util.Stack; libraryDefinition : FEFF? SCRIPT_TAG? - ((metadata LIBRARY) => libraryName)? - ((metadata (IMPORT | EXPORT)) => importOrExport)* - ((metadata PART) => partDirective)* + libraryName? + importOrExport* + partDirective* (metadata topLevelDefinition)* EOF ; @@ -181,16 +137,13 @@ libraryDefinition topLevelDefinition : classDefinition | enumType - | (TYPEDEF typeIdentifier typeParameters? '=') => typeAlias - | (TYPEDEF functionPrefix ('<' | '(')) => typeAlias - | (EXTERNAL functionSignature ';') => EXTERNAL functionSignature ';' - | (EXTERNAL getterSignature) => EXTERNAL getterSignature ';' - | (EXTERNAL type? SET identifier '(') => - EXTERNAL setterSignature ';' - | (getterSignature functionBodyPrefix) => getterSignature functionBody - | (type? SET identifier '(') => setterSignature functionBody - | (type? identifierNotFUNCTION typeParameters? '(') => - functionSignature functionBody + | typeAlias + | EXTERNAL functionSignature ';' + | EXTERNAL getterSignature ';' + | EXTERNAL setterSignature ';' + | getterSignature functionBody + | setterSignature functionBody + | functionSignature functionBody | (FINAL | CONST) type? staticFinalDeclarationList ';' | topLevelVariableDeclaration ';' ; @@ -276,9 +229,8 @@ normalFormalParameter ; normalFormalParameterNoMetadata - : (COVARIANT? type? identifierNotFUNCTION formalParameterPart) => - functionFormalParameter - | (finalConstVarOrType? THIS) => fieldFormalParameter + : functionFormalParameter + | fieldFormalParameter | simpleFormalParameter ; @@ -310,11 +262,9 @@ typeApplication ; classDefinition - : (ABSTRACT? CLASS typeApplication (EXTENDS|IMPLEMENTS|LBRACE)) => - ABSTRACT? CLASS typeApplication (superclass mixins?)? interfaces? + : ABSTRACT? CLASS typeApplication (superclass mixins?)? interfaces? LBRACE (metadata classMemberDefinition)* RBRACE - | (ABSTRACT? CLASS typeApplication '=') => - ABSTRACT? CLASS mixinApplicationClass + | ABSTRACT? CLASS mixinApplicationClass ; mixins @@ -322,18 +272,17 @@ mixins ; classMemberDefinition - : (methodSignature functionBodyPrefix) => methodSignature functionBody + : methodSignature functionBody | declaration ';' ; methodSignature - : (constructorSignature ':') => constructorSignature initializers - | (FACTORY constructorName '(') => factoryConstructorSignature - | (STATIC? type? identifierNotFUNCTION typeParameters? '(') => - STATIC? functionSignature - | (STATIC? type? GET) => STATIC? getterSignature - | (STATIC? type? SET) => STATIC? setterSignature - | (type? OPERATOR operator '(') => operatorSignature + : constructorSignature initializers + | factoryConstructorSignature + | STATIC? functionSignature + | STATIC? getterSignature + | STATIC? setterSignature + | operatorSignature | constructorSignature ; @@ -355,25 +304,17 @@ methodSignature // check. declaration - : (EXTERNAL CONST? FACTORY constructorName '(') => - EXTERNAL factoryConstructorSignature - | (EXTERNAL CONST constructorName '(') => - EXTERNAL constantConstructorSignature - | (EXTERNAL constructorName '(') => EXTERNAL constructorSignature - | ((EXTERNAL STATIC?)? type? GET identifier) => - (EXTERNAL STATIC?)? getterSignature - | ((EXTERNAL STATIC?)? type? SET identifier) => - (EXTERNAL STATIC?)? setterSignature - | (EXTERNAL? type? OPERATOR) => EXTERNAL? operatorSignature - | (STATIC (FINAL | CONST)) => - STATIC (FINAL | CONST) type? staticFinalDeclarationList + : EXTERNAL factoryConstructorSignature + | EXTERNAL constantConstructorSignature + | EXTERNAL constructorSignature + | (EXTERNAL STATIC?)? getterSignature + | (EXTERNAL STATIC?)? setterSignature + | EXTERNAL? operatorSignature + | STATIC (FINAL | CONST) type? staticFinalDeclarationList | FINAL type? initializedIdentifierList - | ((STATIC | COVARIANT)? (VAR | type) identifier ('=' | ',' | ';')) => - (STATIC | COVARIANT)? (VAR | type) initializedIdentifierList - | (EXTERNAL? STATIC? functionSignature ';') => - EXTERNAL? STATIC? functionSignature - | (CONST? FACTORY constructorName formalParameterList '=') => - redirectingFactoryConstructorSignature + | (STATIC | COVARIANT)? (VAR | type) initializedIdentifierList + | EXTERNAL? STATIC? functionSignature + | redirectingFactoryConstructorSignature | constantConstructorSignature (redirection | initializers)? | constructorSignature (redirection | initializers)? ; @@ -400,7 +341,7 @@ operator binaryOperator : multiplicativeOperator | additiveOperator - | (shiftOperator) => shiftOperator + | shiftOperator | relationalOperator | '==' | bitwiseOperator @@ -496,20 +437,16 @@ metadatum ; expression - : (formalParameterPart functionExpressionBodyPrefix) => - functionExpression + : functionExpression | throwExpression - | (assignableExpression assignmentOperator) => - assignableExpression assignmentOperator expression + | assignableExpression assignmentOperator expression | conditionalExpression cascadeSection* ; expressionWithoutCascade - : (formalParameterPart functionExpressionBodyPrefix) => - functionExpressionWithoutCascade + : functionExpressionWithoutCascade | throwExpressionWithoutCascade - | (assignableExpression assignmentOperator) => - assignableExpression assignmentOperator expressionWithoutCascade + | assignableExpression assignmentOperator expressionWithoutCascade | conditionalExpression ; @@ -520,9 +457,9 @@ expressionList primary : thisExpression | SUPER unconditionalAssignableSelector - | (CONST constructorDesignation) => constObjectExpression + | constObjectExpression | newExpression - | (formalParameterPart functionPrimaryBodyPrefix) => functionPrimary + | functionPrimary | '(' expression ')' | literal | identifier @@ -534,7 +471,7 @@ literal | numericLiteral | stringLiteral | symbolLiteral - | (CONST? typeArguments? LBRACE) => mapLiteral + | mapLiteral | listLiteral ; @@ -770,8 +707,8 @@ multiplicativeOperator ; unaryExpression - : (prefixOperator ~SUPER) => prefixOperator unaryExpression - | (awaitExpression) => awaitExpression + : prefixOperator unaryExpression + | awaitExpression | postfixExpression | (minusOperator | tildeOperator) SUPER | incrementOperator assignableExpression @@ -804,11 +741,9 @@ awaitExpression // sequence of two relational expressions. postfixExpression - : (assignableExpression postfixOperator) => - assignableExpression postfixOperator - | (typeName typeArguments '.') => - constructorInvocation ((selector) => selector)* - | primary ((selector) => selector)* + : assignableExpression postfixOperator + | constructorInvocation selector* + | primary selector* ; constructorInvocation @@ -841,15 +776,10 @@ incrementOperator // relationalOperator, not the beginning of typeArguments. assignableExpression - : (SUPER unconditionalAssignableSelector - ~('<' | '(' | '[' | '.' | '?.')) => - SUPER unconditionalAssignableSelector - | (typeName typeArguments '.' identifier '(') => - constructorInvocation - ((assignableSelectorPart) => assignableSelectorPart)+ - | (identifier ~('<' | '(' | '[' | '.' | '?.')) => identifier - | (primary assignableSelectorPart) => - primary ((assignableSelectorPart) => assignableSelectorPart)+ + : SUPER unconditionalAssignableSelector + | constructorInvocation assignableSelectorPart+ + | identifier + | primary assignableSelectorPart+ | identifier ; @@ -891,7 +821,7 @@ identifierNotFUNCTION | ON // Not a built-in identifier. | SHOW // Not a built-in identifier. | SYNC // Not a built-in identifier. - | { asyncEtcPredicate(input.LA(1)) }? (ASYNC|AWAIT|YIELD) + | { asyncEtcPredicate(getCurrentToken().getType()) }? (ASYNC|AWAIT|YIELD) ; identifier @@ -913,7 +843,7 @@ typeIdentifier | ON // Not a built-in identifier. | SHOW // Not a built-in identifier. | SYNC // Not a built-in identifier. - | { asyncEtcPredicate(input.LA(1)) }? (ASYNC|AWAIT|YIELD) + | { asyncEtcPredicate(getCurrentToken().getType()) }? (ASYNC|AWAIT|YIELD) ; typeTest @@ -947,10 +877,9 @@ statement // add another statement which can start with LBRACE we must adjust this // check. nonLabelledStatement - : (LBRACE) => block - | (metadata declaredIdentifier ('='|','|';')) => - localVariableDeclaration - | (AWAIT? FOR) => forStatement + : block + | localVariableDeclaration + | forStatement | whileStatement | doStatement | switchStatement @@ -960,10 +889,9 @@ nonLabelledStatement | breakStatement | continueStatement | returnStatement - | (metadata functionSignature functionBodyPrefix) => - localFunctionDeclaration + | localFunctionDeclaration | assertStatement - | (YIELD ~'*') => yieldStatement + | yieldStatement | yieldEachStatement | expressionStatement ; @@ -985,7 +913,7 @@ localFunctionDeclaration ; ifStatement - : IF '(' expression ')' statement ((ELSE) => ELSE statement | ()) + : IF '(' expression ')' statement (ELSE statement | ()) ; forStatement @@ -993,16 +921,15 @@ forStatement ; forLoopParts - : (metadata declaredIdentifier IN) => - metadata declaredIdentifier IN expression - | (metadata identifier IN) => metadata identifier IN expression + : metadata declaredIdentifier IN expression + | metadata identifier IN expression | forInitializerStatement expression? ';' expressionList? ; // The localVariableDeclaration cannot be CONST, but that can // be enforced in a later phase, and the grammar allows it. forInitializerStatement - : (localVariableDeclaration) => localVariableDeclaration + : localVariableDeclaration | expression? ';' ; @@ -1040,7 +967,7 @@ onPart ; onParts - : (onPart (ON|CATCH)) => onPart onParts + : onPart onParts | onPart ; @@ -1089,8 +1016,8 @@ libraryName ; importOrExport - : (metadata IMPORT) => libraryImport - | (metadata EXPORT) => libraryExport + : libraryImport + | libraryExport ; libraryImport @@ -1132,9 +1059,8 @@ uri ; type - : (FUNCTION ('('|'<')) => functionTypeTails - | (typeNotFunction FUNCTION ('('|'<')) => - typeNotFunction functionTypeTails + : functionTypeTails + | typeNotFunction functionTypeTails | typeNotFunction ; @@ -1144,7 +1070,7 @@ typeNotFunction ; typeNotVoid - : (typeNotFunction? FUNCTION ('('|'<')) => functionType + : functionType | typeNotVoidNotFunction ; @@ -1170,8 +1096,7 @@ typeNotVoidNotFunctionList ; typeAlias - : (TYPEDEF typeIdentifier typeParameters? '=') => - TYPEDEF typeIdentifier typeParameters? '=' functionType ';' + : TYPEDEF typeIdentifier typeParameters? '=' functionType ';' | TYPEDEF functionTypeAlias ; @@ -1180,7 +1105,7 @@ functionTypeAlias ; functionPrefix - : (type identifier) => type identifier + : type identifier | identifier ; @@ -1189,22 +1114,19 @@ functionTypeTail ; functionTypeTails - : (functionTypeTail FUNCTION ('<'|'(')) => - functionTypeTail functionTypeTails + : functionTypeTail functionTypeTails | functionTypeTail ; functionType - : (FUNCTION ('<'|'(')) => functionTypeTails + : functionTypeTails | typeNotFunction functionTypeTails ; parameterTypeList - : ('(' ')') => '(' ')' - | ('(' normalParameterTypes ',' ('['|'{')) => - '(' normalParameterTypes ',' optionalParameterTypes ')' - | ('(' normalParameterTypes ','? ')') => - '(' normalParameterTypes ','? ')' + : '(' ')' + | '(' normalParameterTypes ',' optionalParameterTypes ')' + | '(' normalParameterTypes ','? ')' | '(' optionalParameterTypes ')' ; @@ -1213,7 +1135,7 @@ normalParameterTypes ; normalParameterType - : (typedIdentifier) => typedIdentifier + : typedIdentifier | type ; @@ -1239,9 +1161,8 @@ constructorDesignation | typeName typeArguments ('.' identifier)? ; -// Predicate: Force resolution as composite symbolLiteral as far as possible. symbolLiteral - : '#' (operator | (identifier (('.' identifier) => '.' identifier)*)) + : '#' (operator | (identifier ('.' identifier)*)) ; singleLineStringWithoutInterpolation @@ -1536,7 +1457,7 @@ FUNCTION ; NUMBER - : (DIGIT+ '.' DIGIT) => DIGIT+ '.' DIGIT+ EXPONENT? + : DIGIT+ '.' DIGIT+ EXPONENT? | DIGIT+ EXPONENT? | '.' DIGIT+ EXPONENT? ; @@ -1552,8 +1473,8 @@ RAW_SINGLE_LINE_STRING ; RAW_MULTI_LINE_STRING - : 'r' '"""' (options {greedy=false;} : .)* '"""' - | 'r' '\'\'\'' (options {greedy=false;} : .)* '\'\'\'' + : 'r' '"""' (.)*? '"""' + | 'r' '\'\'\'' (.)*? '\'\'\'' ; fragment @@ -1577,15 +1498,13 @@ SINGLE_LINE_STRING_SQ_BEGIN_MID ; SINGLE_LINE_STRING_SQ_MID_MID - : { currentBraceLevel(BRACE_SINGLE) }? => - ('}' STRING_CONTENT_SQ* '${') => + : { currentBraceLevel(BRACE_SINGLE) }? { exitBrace(); } '}' STRING_CONTENT_SQ* '${' { enterBraceSingleQuote(); } ; SINGLE_LINE_STRING_SQ_MID_END - : { currentBraceLevel(BRACE_SINGLE) }? => - ('}' STRING_CONTENT_SQ* '\'') => + : { currentBraceLevel(BRACE_SINGLE) }? { exitBrace(); } '}' STRING_CONTENT_SQ* '\'' ; @@ -1605,15 +1524,13 @@ SINGLE_LINE_STRING_DQ_BEGIN_MID ; SINGLE_LINE_STRING_DQ_MID_MID - : { currentBraceLevel(BRACE_DOUBLE) }? => - ('}' STRING_CONTENT_DQ* '${') => + : { currentBraceLevel(BRACE_DOUBLE) }? { exitBrace(); } '}' STRING_CONTENT_DQ* '${' { enterBraceDoubleQuote(); } ; SINGLE_LINE_STRING_DQ_MID_END - : { currentBraceLevel(BRACE_DOUBLE) }? => - ('}' STRING_CONTENT_DQ* '"') => + : { currentBraceLevel(BRACE_DOUBLE) }? { exitBrace(); } '}' STRING_CONTENT_DQ* '"' ; @@ -1644,15 +1561,13 @@ MULTI_LINE_STRING_SQ_BEGIN_MID ; MULTI_LINE_STRING_SQ_MID_MID - : { currentBraceLevel(BRACE_THREE_SINGLE) }? => - ('}' STRING_CONTENT_TSQ* QUOTES_SQ '${') => + : { currentBraceLevel(BRACE_THREE_SINGLE) }? { exitBrace(); } '}' STRING_CONTENT_TSQ* QUOTES_SQ '${' { enterBraceThreeSingleQuotes(); } ; MULTI_LINE_STRING_SQ_MID_END - : { currentBraceLevel(BRACE_THREE_SINGLE) }? => - ('}' STRING_CONTENT_TSQ* '\'\'\'') => + : { currentBraceLevel(BRACE_THREE_SINGLE) }? { exitBrace(); } '}' STRING_CONTENT_TSQ* '\'\'\'' ; @@ -1682,15 +1597,13 @@ MULTI_LINE_STRING_DQ_BEGIN_MID ; MULTI_LINE_STRING_DQ_MID_MID - : { currentBraceLevel(BRACE_THREE_DOUBLE) }? => - ('}' STRING_CONTENT_TDQ* QUOTES_DQ '${') => + : { currentBraceLevel(BRACE_THREE_DOUBLE) }? { exitBrace(); } '}' STRING_CONTENT_TDQ* QUOTES_DQ '${' { enterBraceThreeDoubleQuotes(); } ; MULTI_LINE_STRING_DQ_MID_END - : { currentBraceLevel(BRACE_THREE_DOUBLE) }? => - ('}' STRING_CONTENT_TDQ* '"""') => + : { currentBraceLevel(BRACE_THREE_DOUBLE) }? { exitBrace(); } '}' STRING_CONTENT_TDQ* '"""' ; @@ -1699,7 +1612,7 @@ LBRACE ; RBRACE - : { currentBraceLevel(BRACE_NORMAL) }? => ('}') => { exitBrace(); } '}' + : { currentBraceLevel(BRACE_NORMAL) }? { exitBrace(); } '}' ; fragment @@ -1745,7 +1658,7 @@ SINGLE_LINE_COMMENT ; MULTI_LINE_COMMENT - : '/*' (options {greedy=false;} : (MULTI_LINE_COMMENT | .))* '*/' + : '/*' (MULTI_LINE_COMMENT | .)*? '*/' { skip(); } ; diff --git a/tools/spec_parser/Makefile b/tools/spec_parser/Makefile index f91e7d3e366..dca1088e70f 100644 --- a/tools/spec_parser/Makefile +++ b/tools/spec_parser/Makefile @@ -6,9 +6,9 @@ GRAMMAR=../../docs/language/Dart.g JAVA_PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin JAVA=$(JAVA_PATH)/java JAVAC=javac -ANTLR_JAR=/usr/share/java/antlr3-runtime.jar +ANTLR_JAR=/usr/share/java/antlr4-runtime.jar ANTLR_FILES=DartLexer.java DartParser.java Dart.tokens -ANTLR_CMD=PATH=$(JAVA_PATH):$(PATH) antlr3 -dfa -fo . $< +ANTLR_CMD=PATH=$(JAVA_PATH):$(PATH) antlr4 $< JAVA_FILES=DartLexer.java DartParser.java CLASS_FILES=SpecParser.class SpecParserRunner.class DartLexer.class DartParser.class @@ -21,11 +21,11 @@ parser: SpecParser.class SpecParser.class: $(ANTLR_FILES) SpecParser.java $(JAVAC) -cp .:$(ANTLR_JAR) SpecParser.java -%Lexer.java: ../../docs/language/%.g Makefile ; $(ANTLR_CMD) +%Lexer.java: %.g Makefile ; $(ANTLR_CMD) -%Parser.java: ../../docs/language/%.g Makefile ; $(ANTLR_CMD) +%Parser.java: %.g Makefile ; $(ANTLR_CMD) -%.tokens: ../../docs/language/%.g Makefile ; $(ANTLR_CMD) +%.tokens: %.g Makefile ; $(ANTLR_CMD) clean: rm -f $(CLASS_FILES) $(ANTLR_FILES) diff --git a/tools/spec_parser/SpecParser.java b/tools/spec_parser/SpecParser.java index 0f6ba684d21..cc9d1ea6a13 100644 --- a/tools/spec_parser/SpecParser.java +++ b/tools/spec_parser/SpecParser.java @@ -4,13 +4,52 @@ import java.io.*; import java.util.*; -import org.antlr.runtime.*; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.dfa.*; +import org.antlr.v4.runtime.atn.*; class ParsingResult { public int numberOfFileArguments; public int numberOfFailures; } +class DartErrorListener implements ANTLRErrorListener { + public void reportAmbiguity( + Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + boolean exact, + BitSet ambigAlts, + ATNConfigSet configs) {} + + public void reportAttemptingFullContext( + Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + BitSet conflictingAlts, + ATNConfigSet configs) {} + + public void reportContextSensitivity( + Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + int prediction, + ATNConfigSet configs) {} + + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + if (!DartParser.errorHasOccurred) DartParser.prepareForErrors(); + } +} + /// Class for `main` which will parse files given as command line arguments. public class SpecParser { private static void normalExit() { @@ -83,8 +122,11 @@ public class SpecParser { continue; } if (verbose) System.err.println("Parsing file: " + filePath); - DartParser parser = new DartParser(new CommonTokenStream( - new DartLexer(new ANTLRFileStream(filePath)))); + DartLexer lexer = new DartLexer(new ANTLRFileStream(filePath)); + DartParser parser = new DartParser(new CommonTokenStream(lexer)); + ANTLRErrorListener errorListener = new DartErrorListener(); + lexer.addErrorListener(errorListener); + parser.addErrorListener(errorListener); if (!parser.parseLibrary(filePath)) result.numberOfFailures++; } return result;