# Adapted from http://www.antlr.org/grammar/1152141644268/Java.g # [The "BSD licence"] # Copyright (c) 2007-2008 Terence Parr # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =begin overview This is the grammar for java written as a sequence of Perl 6 rules. =end overview grammar java::Grammar is PCT::Grammar; rule TOP { [ $ || ] {*} } token ws { | + | * } token ws_all { | \h+ | \v+ | '//' \N* | '/*' .*? '*/' } rule compilationUnit { | + [ | * * | * ] | ? * * } rule packageDeclaration { {{ say 'start package' }} 'package' ';' {{ say 'package!' }} } rule importDeclaration { {{ say 'start import' }} 'import' 'static'? ['.' '*']? ';' {*} {{ say 'import!' }} } rule typeDeclaration { | | ';' } rule classOrInterfaceDeclaration { {{ say 'start classorinterface' }} [ | ] {{ say 'classorinterface!' }} } rule classOrInterfaceModifiers { {{ say 'start classorintermods' }} * {{ say 'classorintermods!' }} } rule classOrInterfaceModifier { | | 'public' | 'protected' | 'private' | 'abstract' | 'static' | 'final' | 'strictfp' } rule modifiers { {{ say 'start mods' }} * {{ say 'mods!' }} } rule classDeclaration { | | } rule normalClassDeclaration { {{ say 'start class' }} 'class' ? ['extends' ]? ['implements' ]? {*} #= start {{ say 'class! now body' }} {{ say 'class body!' }} } rule typeParameters { '<' [ ',' ]* '>' } rule typeParameter { ['extends' ]? } rule typeBound { [ '&' ]* } rule enumDeclaration { {{ say 'start enum' }} ['implements' ]? {{ say 'enum!' }} {{ say 'enum body!' }} } rule enumBody { '{' ? ','? ? '}' } rule enumConstants { [ ',' ]* } rule enumConstant { ? ? ? } rule enumBodyDeclarations { ';' * } rule interfaceDeclaration { | | } rule normalInterfaceDeclaration { {{ say 'start interface' }} 'interface' ? ['extends' ]? {{ say 'interface!' }} {{ say 'interface body!' }} } rule typeList { [ ',' ]* } rule classBody { '{' * '}' } rule interfaceBody { '{' * '}' } rule classBodyDeclaration { | ';' | 'static'? | } rule memberDecl { | | | 'void' | | | } rule memberDeclaration { {{ say 'start member' }} [ | ] {{ say 'member!' }} } rule genericMethodOrConstructorDecl { {{ say 'start genericMethOrCons' }} {{ say 'genericMethOrCons!' }} } rule genericMethodOrConstructorRest { | [ | 'void'] | } rule methodDeclaration { {{ say 'start method' }} {*} {{ say 'method!' }} } rule fieldDeclaration { {{ say 'start field' }} ';' {*} {{ say 'field!' }} } rule interfaceBodyDeclaration { | | ';' } rule interfaceMemberDecl { | | | 'void' | | } rule interfaceMethodOrFieldDecl { } rule interfaceMethodOrFieldRest { | ';' | } rule methodDeclaratorRest { {{ say 'start methRest' }} [ '[' ']' ]* ['throws' ]? {{ say 'methRest!' }} [ | ';' ] {{ say 'methRest and body!' }} } rule voidMethodDeclaratorRest { ['throws' ]? [ | ';' ] } rule interfaceMethodDeclaratorRest { [ '[' ']' ]* ['throws' ]? ';' } rule interfaceGenericMethodDecl { [ | 'void'] } rule voidInterfaceMethodDeclaratorRest { ['throws' ]? ';' } rule constructorDeclaratorRest { {{ say 'start constr' }} ['throws' ]? {{ say 'constr!' }} {{ say 'constr body!' }} } rule constantDeclarator { } rule variableDeclarators { [ ',' ]* } rule variableDeclarator { [ '=' ]? } rule constantDeclaratorsRest { [ ',' ]* } rule constantDeclaratorRest { [ '[' ']' ]* '=' } rule variableDeclaratorId { [ '[' ']' ]* } rule variableInitializer { | | } rule arrayInitializer { '{' [ [ ',' ]* [',']? ]? '}' } rule modifier { | | 'public' | 'protected' | 'private' | 'static' | 'abstract' | 'final' | 'native' | 'synchronized' | 'transient' | 'volatile' | 'strictfp' } rule packageOrTypeName { } rule enumConstantName { } rule typeName { } rule type { | [ '[' ']' ]* | [ '[' ']' ]* } rule classOrInterfaceType { ? [ '.' ? ]* } rule primitiveType { | 'boolean' | 'char' | 'byte' | 'short' | 'int' | 'long' | 'float' | 'double' } rule variableModifier { | 'final' | } rule typeArguments { '<' [ ',' ]* '>' } rule typeArgument { | | '?' [ [ 'extends' | 'super' ] ]? } rule qualifiedNameList { [ ',' ]* } rule formalParameters { '(' ? ')' } rule formalParameterDecls { } rule formalParameterDeclsRest { | [ ',' ]? | '...' } rule methodBody { } rule constructorBody { {{ say 'start constr body' }} '{' ? * '}' {{ say 'constr body!' }} } rule explicitConstructorInvocation { | ? ['this' | 'super'] ';' | '.' ? 'super' ';' } rule qualifiedName { [ '.' ]* } rule literal { | | | | | | | | 'null' } rule booleanLiteral { | 'true' | 'false' } # // ANNOTATIONS rule annotations { + } rule annotation { {{ say 'start annotation' }} '@' {*} [ '(' [ | ]? ')' ]? {{ say 'annotation!' }} } rule annotationName { [ '.' ]* } rule elementValuePairs { [ ',' ]* } rule elementValuePair { '=' } rule elementValue { | | | } rule elementValueArrayInitializer { '{' [ [ ',' ]*]? [',']? '}' } rule annotationTypeDeclaration { '@' 'interface' } rule annotationTypeBody { '{' [ ]* '}' } rule annotationTypeElementDeclaration { } rule annotationTypeElementRest { | ';' | ';'? | ';'? | ';'? | ';'? } rule annotationMethodOrConstantRest { | | } rule annotationMethodRest { '(' ')' ? } rule annotationConstantRest { } rule defaultValue { 'default' } # // STATEMENTS / BLOCKS rule block { {{ say 'start block' }} '{' * '}' {*} {{ say 'block!' }} } rule blockStatement { | | | {*} } rule localVariableDeclarationStatement { ';' } rule localVariableDeclaration { {*} } rule variableModifiers { * } rule statement { | | [':' ]? ';' | 'if' {{ say 'if...' }} ['else' {{ say 'else...' }} ]? | 'for' '(' ')' | 'while' | 'do' 'while' ';' | 'try' [ 'finally' | | 'finally' ] | 'switch' '{' '}' | 'synchronized' | 'return' ? ';' | 'throw' ';' | 'break' ? ';' | 'continue' ? ';' | ';' | ';' | ':' } rule catches { [ ]+ } rule catchClause { 'catch' '(' ')' } rule formalParameter { } rule switchBlockStatementGroups { [ ]* } # /* The change here (switchLabel -> switchLabel+) technically makes this grammar # ambiguous; but with appropriately greedy parsing it yields the most # appropriate AST, one in which each group, except possibly the last one, has # labels and statements. */ rule switchBlockStatementGroup { + * } rule switchLabel { | 'case' ':' {*} #= normal | 'case' ':' {*} #= enum | 'default' ':' {*} #= default } rule forControl { | | ? ';' ? ';' ? } rule forInit { | | } rule enhancedForControl { ':' } rule forUpdate { } # // EXPRESSIONS rule parExpression { '(' ')' {*} } rule expressionList { [ ',' ]* } rule statementExpression { } rule constantExpression { } rule expression { [ ]? {*} } rule assignmentOperator { | '=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '%=' | '<<=' | '>>>=' | '>>=' } rule conditionalExpression { [ '?' ':' ]? } rule conditionalOrExpression { [ '||' ]* } rule conditionalAndExpression { [ '&&' ]* } rule inclusiveOrExpression { [ '|' ]* } rule exclusiveOrExpression { [ '^' ]* } rule andExpression { [ '&' ]* } rule equalityExpression { [ ['==' | '!='] ]* } rule instanceOfExpression { ['instanceof' {{ say 'instanceof!' }}]? } rule relationalExpression { [ ]* } rule relationalOp { | '<=' | '>=' | '<' | '>' } rule shiftExpression { [ ]* } rule shiftOp { | '<<' | '>>>' | '>>' } rule additiveExpression { [ ['+' | '-'] ]* } rule multiplicativeExpression { [ [ '*' | '/' | '%' ] ]* } rule unaryExpression { | '+' | '-' | '++' | '--' | } rule unaryExpressionNotPlusMinus { | '~' | '!' | | * ['++'|'--']? } rule castExpression { | '(' ')' | '(' [ | ] ')' } rule primary { | | 'this' # added the 'before' to work around a longest-token problem [ '.' ]* ? {*} | 'super' | | 'new' | [ '.' ]* ? | [ '[' ']' ]* '.' 'class' | 'void' '.' 'class' } rule IdentifierSuffix { | [ '[' ']' ]+ '.' 'class' | [ '[' ']' ]+ # // can also be matched by selector, but do here | | '.' 'class' | '.' | '.' 'this' | '.' 'super' | '.' 'new' } rule creator { | | [ | ] } rule createdName { | | } rule innerCreator { ? } rule arrayCreatorRest { {{ say 'start arrayCreatorRest' }} '[' {{ say 'arrayCreatorRest got open' }} [ ']' [ '[' ']' ]* | {*} ']' [ '[' ']' ]* [ '[' ']' ]* ] {{ say 'arrayCreatorRest!' }} } rule classCreatorRest { ? } rule explicitGenericInvocation { } rule nonWildcardTypeArguments { '<' '>' } rule selector { | '.' 'this' | '.' 'super' | '.' 'new' | '.' ? | '[' ']' } rule superSuffix { | '.' ? } rule arguments { '(' ? ')' } # // LEXER token HexLiteral { '0' ['x'|'X'] [ | '.' + ? ? | + [ '.' * ? ? | ? ] ] } token HexDigit { \d|<[a..f]>|<[A..F]> } token HexExponent { ['p'|'P'] ['+'|'-']? \d+ } token OctalLiteral { '0' <[0..7]>+ ? } token DecimalLiteral { ['0' | <[1..9]> \d*] ? } token IntegerTypeSuffix { 'l'|'L' } token FloatingPointLiteral { | \d+ '.' \d* ? ? | '.' \d+ ? ? | \d+ ? | \d+ } token Exponent { ['e'|'E'] ['+'|'-']? \d+ } token FloatTypeSuffix { 'f'|'F'|'d'|'D' } token CharacterLiteral { '\'' [ | <-esc_single_quote> ] '\'' } token StringLiteral { '"' [ | <-esc_double_quote> ]* '"' } token esc_single_quote { '\\' | '\'' } token esc_double_quote { '\\' | '"' } token EscapeSequence { | '\\' ['b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\'] | | } token OctalEscape { '\\' [ | <[0..3]> <[0..7]> <[0..7]> | <[0..7]> <[0..7]> | <[0..7]> ] } token UnicodeEscape { '\\u' **{4} } token ENUM { 'enum' } token ASSERT { 'assert' } token Identifier { \W><.ident> } token keyword { # from http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.9 'abstract' | 'continue' | 'for' | 'new' | 'switch' 'assert' | 'default' | 'if' | 'package' | 'synchronized' 'boolean' | 'do' | 'goto' | 'private' | 'this' 'break' | 'double' | 'implements' | 'protected' | 'throw' 'byte' | 'else' | 'import' | 'public' | 'throws' 'case' | 'enum' | 'instanceof' | 'return' | 'transient' 'catch' | 'extends' | 'int' | 'short' | 'try' 'char' | 'final' | 'interface' | 'static' | 'void' 'class' | 'finally' | 'long' | 'strictfp' | 'volatile' 'const' | 'float' | 'native' | 'super' | 'while' }