diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g index 669061370e5..c4bd68435dd 100644 --- a/tools/spec_parser/Dart.g +++ b/tools/spec_parser/Dart.g @@ -4,6 +4,8 @@ // CHANGES: // +// v0.53 Support declaring constructors. +// // v0.52 Support static access shorthands. // // v0.51 Support a `switchExpression` with no cases. @@ -176,18 +178,14 @@ import java.util.Stack; @parser::members { static String filePath = null; static boolean errorHasOccurred = false; - - /// Must be invoked before the first error is reported for a library. - /// Will print the name of the library and indicate that it has errors. - static void prepareForErrors() { - errorHasOccurred = true; - System.err.println("Syntax error in " + filePath + ":"); - } + static boolean errorHeaderHasBeenPrinted = false; /// Parse library, return true if success, false if errors occurred. public boolean parseLibrary(String filePath) throws RecognitionException { this.filePath = filePath; - errorHasOccurred = false; + errorHeaderHasBeenPrinted = false; + this.removeErrorListeners(); // Remove the default ConsoleErrorListener. + this.addErrorListener(new DartErrorListener()); // Add our custom one. startSymbol(); return !errorHasOccurred; } @@ -397,13 +395,11 @@ functionFormalParameter ; simpleFormalParameter - : declaredIdentifier - | COVARIANT? identifier + : COVARIANT? type? identifier ; -// NB: It is an anomaly that VAR can be a return type (`var this.x()`). fieldFormalParameter - : finalConstVarOrType? THIS '.' identifier (formalParameterPart '?'?)? + : type? THIS '.' identifier (formalParameterPart '?'?)? ; superFormalParameter @@ -424,11 +420,25 @@ typeWithParameters classDeclaration : AUGMENT? (classModifiers | mixinClassModifiers) - CLASS typeWithParameters superclass? interfaces? - LBRACE (metadata classMemberDeclaration)* RBRACE + CLASS classNamePart superclass? interfaces? classBody | classModifiers MIXIN? CLASS mixinApplicationClass ; +primaryConstructorNoConst + : typeIdentifier typeParameters? + ('.' identifierOrNew)? declaringParameterList + ; + +classNamePart + : CONST? primaryConstructorNoConst + | typeWithParameters + ; + +classBody + : LBRACE (metadata classMemberDeclaration)* RBRACE + | ';' + ; + classModifiers : SEALED | ABSTRACT? (BASE | INTERFACE | FINAL)? @@ -466,25 +476,21 @@ mixinDeclaration LBRACE (metadata mixinMemberDeclaration)* RBRACE ; -// TODO: We might want to make this more strict. mixinMemberDeclaration : classMemberDeclaration ; extensionTypeDeclaration - : EXTENSION TYPE CONST? typeWithParameters - representationDeclaration interfaces? - LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE + : EXTENSION TYPE classNamePart interfaces? extensionTypeBody | AUGMENT EXTENSION TYPE typeWithParameters interfaces? - LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE + extensionTypeBody ; -representationDeclaration - : ('.' identifierOrNew)? '(' metadata typedIdentifier ')' +extensionTypeBody + : LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE + | ';' ; - -// TODO: We might want to make this more strict. extensionTypeMemberDeclaration : classMemberDeclaration ; @@ -498,7 +504,6 @@ extensionBody : LBRACE (metadata extensionMemberDeclaration)* RBRACE ; -// TODO: We might want to make this more strict. extensionMemberDeclaration : classMemberDeclaration ; @@ -564,13 +569,82 @@ setterSignature constructorSignature : constructorName formalParameterList + | declaringConstructorSignature + ; + +declaringConstructorSignature + : THIS ('.' identifierOrNew)? declaringParameterList? + ; + +declaringConstantConstructorSignature + : CONST THIS ('.' identifierOrNew)? declaringParameterList + ; + +declaringParameterList + : '(' ')' + | '(' declaringFormalParameters ','? ')' + | '(' declaringFormalParameters ',' + optionalOrNamedDeclaringFormalParameters ')' + | '(' optionalOrNamedDeclaringFormalParameters ')' + ; + +declaringFormalParameters + : declaringFormalParameter (',' declaringFormalParameter)* + ; + +declaringFormalParameter + : metadata declaringFormalParameterNoMetadata + ; + +declaringFormalParameterNoMetadata + : declaringFunctionFormalParameter + | fieldFormalParameter + | declaringSimpleFormalParameter + | superFormalParameter + ; + +declaringFunctionFormalParameter + : COVARIANT? (VAR | FINAL)? type? + identifier formalParameterPart '?'? + ; + +declaringSimpleFormalParameter + : COVARIANT? (VAR | FINAL)? type? identifier + ; + +optionalOrNamedDeclaringFormalParameters + : optionalPositionalDeclaringFormalParameters + | namedDeclaringFormalParameters + ; + +optionalPositionalDeclaringFormalParameters + : '[' defaultDeclaringFormalParameter + (',' defaultDeclaringFormalParameter)* ','? ']' + ; + +defaultDeclaringFormalParameter + : declaringFormalParameter ('=' expression)? + ; + +namedDeclaringFormalParameters + : LBRACE defaultDeclaringNamedParameter + (',' defaultDeclaringNamedParameter)* ','? RBRACE + ; + +defaultDeclaringNamedParameter + : metadata REQUIRED? declaringFormalParameterNoMetadata + ('=' expression)? ; constructorName - : typeIdentifier ('.' identifierOrNew)? + : typeIdentifierOrNew ('.' identifierOrNew)? + ; + +typeIdentifierOrNew + : typeIdentifier + | NEW ; -// TODO: Add this in the language specification, use it in grammar rules. identifierOrNew : identifier | NEW @@ -613,6 +687,7 @@ redirectingFactoryConstructorSignature constantConstructorSignature : CONST constructorName formalParameterList + | declaringConstantConstructorSignature ; mixinApplication @@ -620,8 +695,8 @@ mixinApplication ; enumType - : AUGMENT? ENUM typeWithParameters mixins? interfaces? LBRACE - enumEntry (',' enumEntry)* (',')? + : AUGMENT? ENUM classNamePart mixins? interfaces? LBRACE + enumEntry (',' enumEntry)* ','? (';' (metadata classMemberDeclaration)*)? RBRACE ; diff --git a/tools/spec_parser/SpecParser.java b/tools/spec_parser/SpecParser.java index 7f682e586c0..e218ef82565 100644 --- a/tools/spec_parser/SpecParser.java +++ b/tools/spec_parser/SpecParser.java @@ -14,6 +14,7 @@ class ParsingResult { } class DartErrorListener implements ANTLRErrorListener { + @Override public void reportAmbiguity( Parser recognizer, DFA dfa, @@ -23,6 +24,7 @@ class DartErrorListener implements ANTLRErrorListener { BitSet ambigAlts, ATNConfigSet configs) {} + @Override public void reportAttemptingFullContext( Parser recognizer, DFA dfa, @@ -31,6 +33,7 @@ class DartErrorListener implements ANTLRErrorListener { BitSet conflictingAlts, ATNConfigSet configs) {} + @Override public void reportContextSensitivity( Parser recognizer, DFA dfa, @@ -39,14 +42,19 @@ class DartErrorListener implements ANTLRErrorListener { int prediction, ATNConfigSet configs) {} - public void syntaxError( - Recognizer recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { - if (!DartParser.errorHasOccurred) DartParser.prepareForErrors(); + @Override + public void syntaxError(Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + DartParser.errorHasOccurred = true; + if (!DartParser.errorHeaderHasBeenPrinted) { + System.err.println("Syntax error in " + DartParser.filePath + ":"); + DartParser.errorHeaderHasBeenPrinted = true; + } + System.err.println("line " + line + ":" + charPositionInLine + " " + msg); } } diff --git a/tools/spec_parser/dart_spec_parser/Dart.g4 b/tools/spec_parser/dart_spec_parser/Dart.g4 index 3ea374425d9..7175ec0397d 100644 --- a/tools/spec_parser/dart_spec_parser/Dart.g4 +++ b/tools/spec_parser/dart_spec_parser/Dart.g4 @@ -4,6 +4,8 @@ // CHANGES: // +// v0.54 Support declaring constructors. +// // v0.53 Support static access shorthands. // // v0.52 Support a `switchExpression` with no cases. @@ -403,13 +405,11 @@ functionFormalParameter ; simpleFormalParameter - : declaredIdentifier - | COVARIANT? identifier + : COVARIANT? type? identifier ; -// NB: It is an anomaly that VAR can be a return type (`var this.x()`). fieldFormalParameter - : finalConstVarOrType? THIS '.' identifier (formalParameterPart '?'?)? + : type? THIS '.' identifier (formalParameterPart '?'?)? ; superFormalParameter @@ -430,11 +430,25 @@ typeWithParameters classDeclaration : AUGMENT? (classModifiers | mixinClassModifiers) - CLASS typeWithParameters superclass? interfaces? - LBRACE (metadata classMemberDeclaration)* RBRACE + CLASS classNamePart superclass? interfaces? classBody | classModifiers MIXIN? CLASS mixinApplicationClass ; +primaryConstructorNoConst + : typeIdentifier typeParameters? + ('.' identifierOrNew)? declaringParameterList + ; + +classNamePart + : CONST? primaryConstructorNoConst + | typeWithParameters + ; + +classBody + : LBRACE (metadata classMemberDeclaration)* RBRACE + | ';' + ; + classModifiers : SEALED | ABSTRACT? (BASE | INTERFACE | FINAL)? @@ -472,25 +486,21 @@ mixinDeclaration LBRACE (metadata mixinMemberDeclaration)* RBRACE ; -// TODO: We might want to make this more strict. mixinMemberDeclaration : classMemberDeclaration ; extensionTypeDeclaration - : EXTENSION TYPE CONST? typeWithParameters - representationDeclaration interfaces? - LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE + : EXTENSION TYPE classNamePart interfaces? extensionTypeBody | AUGMENT EXTENSION TYPE typeWithParameters interfaces? - LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE + extensionTypeBody ; -representationDeclaration - : ('.' identifierOrNew)? '(' metadata typedIdentifier ')' +extensionTypeBody + : LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE + | ';' ; - -// TODO: We might want to make this more strict. extensionTypeMemberDeclaration : classMemberDeclaration ; @@ -570,13 +580,82 @@ setterSignature constructorSignature : constructorName formalParameterList + | declaringConstructorSignature + ; + +declaringConstructorSignature + : THIS ('.' identifierOrNew)? declaringParameterList? + ; + +declaringConstantConstructorSignature + : CONST THIS ('.' identifierOrNew)? declaringParameterList + ; + +declaringParameterList + : '(' ')' + | '(' declaringFormalParameters ','? ')' + | '(' declaringFormalParameters ',' + optionalOrNamedDeclaringFormalParameters ')' + | '(' optionalOrNamedDeclaringFormalParameters ')' + ; + +declaringFormalParameters + : declaringFormalParameter (',' declaringFormalParameter)* + ; + +declaringFormalParameter + : metadata declaringFormalParameterNoMetadata + ; + +declaringFormalParameterNoMetadata + : declaringFunctionFormalParameter + | fieldFormalParameter + | declaringSimpleFormalParameter + | superFormalParameter + ; + +declaringFunctionFormalParameter + : COVARIANT? (VAR | FINAL)? type? + identifier formalParameterPart '?'? + ; + +declaringSimpleFormalParameter + : COVARIANT? (VAR | FINAL)? type? identifier + ; + +optionalOrNamedDeclaringFormalParameters + : optionalPositionalDeclaringFormalParameters + | namedDeclaringFormalParameters + ; + +optionalPositionalDeclaringFormalParameters + : '[' defaultDeclaringFormalParameter + (',' defaultDeclaringFormalParameter)* ','? ']' + ; + +defaultDeclaringFormalParameter + : declaringFormalParameter ('=' expression)? + ; + +namedDeclaringFormalParameters + : LBRACE defaultDeclaringNamedParameter + (',' defaultDeclaringNamedParameter)* ','? RBRACE + ; + +defaultDeclaringNamedParameter + : metadata REQUIRED? declaringFormalParameterNoMetadata + ('=' expression)? ; constructorName - : typeIdentifier ('.' identifierOrNew)? + : typeIdentifierOrNew ('.' identifierOrNew)? + ; + +typeIdentifierOrNew + : typeIdentifier + | NEW ; -// TODO: Add this in the language specification, use it in grammar rules. identifierOrNew : identifier | NEW @@ -619,6 +698,7 @@ redirectingFactoryConstructorSignature constantConstructorSignature : CONST constructorName formalParameterList + | declaringConstantConstructorSignature ; mixinApplication @@ -626,8 +706,8 @@ mixinApplication ; enumType - : AUGMENT? ENUM typeWithParameters mixins? interfaces? LBRACE - enumEntry (',' enumEntry)* (',')? + : AUGMENT? ENUM classNamePart mixins? interfaces? LBRACE + enumEntry (',' enumEntry)* ','? (';' (metadata classMemberDeclaration)*)? RBRACE ;