757 lines
16 KiB
Plaintext
757 lines
16 KiB
Plaintext
parser grammar JavaParser;
|
|
options {backtrack=true; memoize=true; tokenVocab=JavaLexer;}
|
|
|
|
// starting point for parsing a java file
|
|
/* The annotations are separated out to make parsing faster, but must be associated with
|
|
a packageDeclaration or a typeDeclaration (and not an empty one). */
|
|
compilationUnit
|
|
: annotations
|
|
( packageDeclaration importDeclaration* typeDeclaration*
|
|
| classOrInterfaceDeclaration typeDeclaration*
|
|
)
|
|
| packageDeclaration? importDeclaration* typeDeclaration*
|
|
;
|
|
|
|
packageDeclaration
|
|
: 'package' qualifiedName ';'
|
|
;
|
|
|
|
importDeclaration
|
|
: 'import' 'static'? qualifiedName ('.' '*')? ';'
|
|
;
|
|
|
|
typeDeclaration
|
|
: classOrInterfaceDeclaration
|
|
| ';'
|
|
;
|
|
|
|
classOrInterfaceDeclaration
|
|
: classOrInterfaceModifiers (classDeclaration | interfaceDeclaration)
|
|
;
|
|
|
|
classOrInterfaceModifiers
|
|
: classOrInterfaceModifier*
|
|
;
|
|
|
|
classOrInterfaceModifier
|
|
: annotation // class or interface
|
|
| 'public' // class or interface
|
|
| 'protected' // class or interface
|
|
| 'private' // class or interface
|
|
| 'abstract' // class or interface
|
|
| 'static' // class or interface
|
|
| 'final' // class only -- does not apply to interfaces
|
|
| 'strictfp' // class or interface
|
|
;
|
|
|
|
modifiers
|
|
: modifier*
|
|
;
|
|
|
|
classDeclaration
|
|
: normalClassDeclaration
|
|
| enumDeclaration
|
|
;
|
|
|
|
normalClassDeclaration
|
|
: 'class' Identifier typeParameters?
|
|
('extends' type)?
|
|
('implements' typeList)?
|
|
classBody
|
|
;
|
|
|
|
typeParameters
|
|
: '<' typeParameter (',' typeParameter)* '>'
|
|
;
|
|
|
|
typeParameter
|
|
: Identifier ('extends' typeBound)?
|
|
;
|
|
|
|
typeBound
|
|
: type ('&' type)*
|
|
;
|
|
|
|
enumDeclaration
|
|
: ENUM Identifier ('implements' typeList)? enumBody
|
|
;
|
|
|
|
enumBody
|
|
: '{' enumConstants? ','? enumBodyDeclarations? '}'
|
|
;
|
|
|
|
enumConstants
|
|
: enumConstant (',' enumConstant)*
|
|
;
|
|
|
|
enumConstant
|
|
: annotations? Identifier arguments? classBody?
|
|
;
|
|
|
|
enumBodyDeclarations
|
|
: ';' (classBodyDeclaration)*
|
|
;
|
|
|
|
interfaceDeclaration
|
|
: normalInterfaceDeclaration
|
|
| annotationTypeDeclaration
|
|
;
|
|
|
|
normalInterfaceDeclaration
|
|
: 'interface' Identifier typeParameters? ('extends' typeList)? interfaceBody
|
|
;
|
|
|
|
typeList
|
|
: type (',' type)*
|
|
;
|
|
|
|
classBody
|
|
: '{' classBodyDeclaration* '}'
|
|
;
|
|
|
|
interfaceBody
|
|
: '{' interfaceBodyDeclaration* '}'
|
|
;
|
|
|
|
classBodyDeclaration
|
|
: ';'
|
|
| 'static'? block
|
|
| modifiers memberDecl
|
|
;
|
|
|
|
memberDecl
|
|
: genericMethodOrConstructorDecl
|
|
| memberDeclaration
|
|
| 'void' Identifier voidMethodDeclaratorRest
|
|
| Identifier constructorDeclaratorRest
|
|
| interfaceDeclaration
|
|
| classDeclaration
|
|
;
|
|
|
|
memberDeclaration
|
|
: type (methodDeclaration | fieldDeclaration)
|
|
;
|
|
|
|
genericMethodOrConstructorDecl
|
|
: typeParameters genericMethodOrConstructorRest
|
|
;
|
|
|
|
genericMethodOrConstructorRest
|
|
: (type | 'void') Identifier methodDeclaratorRest
|
|
| Identifier constructorDeclaratorRest
|
|
;
|
|
|
|
methodDeclaration
|
|
: Identifier methodDeclaratorRest
|
|
;
|
|
|
|
fieldDeclaration
|
|
: variableDeclarators ';'
|
|
;
|
|
|
|
interfaceBodyDeclaration
|
|
: modifiers interfaceMemberDecl
|
|
| ';'
|
|
;
|
|
|
|
interfaceMemberDecl
|
|
: interfaceMethodOrFieldDecl
|
|
| interfaceGenericMethodDecl
|
|
| 'void' Identifier voidInterfaceMethodDeclaratorRest
|
|
| interfaceDeclaration
|
|
| classDeclaration
|
|
;
|
|
|
|
interfaceMethodOrFieldDecl
|
|
: type Identifier interfaceMethodOrFieldRest
|
|
;
|
|
|
|
interfaceMethodOrFieldRest
|
|
: constantDeclaratorsRest ';'
|
|
| interfaceMethodDeclaratorRest
|
|
;
|
|
|
|
methodDeclaratorRest
|
|
: formalParameters ('[' ']')*
|
|
('throws' qualifiedNameList)?
|
|
( methodBody
|
|
| ';'
|
|
)
|
|
;
|
|
|
|
voidMethodDeclaratorRest
|
|
: formalParameters ('throws' qualifiedNameList)?
|
|
( methodBody
|
|
| ';'
|
|
)
|
|
;
|
|
|
|
interfaceMethodDeclaratorRest
|
|
: formalParameters ('[' ']')* ('throws' qualifiedNameList)? ';'
|
|
;
|
|
|
|
interfaceGenericMethodDecl
|
|
: typeParameters (type | 'void') Identifier
|
|
interfaceMethodDeclaratorRest
|
|
;
|
|
|
|
voidInterfaceMethodDeclaratorRest
|
|
: formalParameters ('throws' qualifiedNameList)? ';'
|
|
;
|
|
|
|
constructorDeclaratorRest
|
|
: formalParameters ('throws' qualifiedNameList)? constructorBody
|
|
;
|
|
|
|
constantDeclarator
|
|
: Identifier constantDeclaratorRest
|
|
;
|
|
|
|
variableDeclarators
|
|
: variableDeclarator (',' variableDeclarator)*
|
|
;
|
|
|
|
variableDeclarator
|
|
: variableDeclaratorId ('=' variableInitializer)?
|
|
;
|
|
|
|
constantDeclaratorsRest
|
|
: constantDeclaratorRest (',' constantDeclarator)*
|
|
;
|
|
|
|
constantDeclaratorRest
|
|
: ('[' ']')* '=' variableInitializer
|
|
;
|
|
|
|
variableDeclaratorId
|
|
: Identifier ('[' ']')*
|
|
;
|
|
|
|
variableInitializer
|
|
: arrayInitializer
|
|
| expression
|
|
;
|
|
|
|
arrayInitializer
|
|
: '{' (variableInitializer (',' variableInitializer)* (',')? )? '}'
|
|
;
|
|
|
|
modifier
|
|
: annotation
|
|
| 'public'
|
|
| 'protected'
|
|
| 'private'
|
|
| 'static'
|
|
| 'abstract'
|
|
| 'final'
|
|
| 'native'
|
|
| 'synchronized'
|
|
| 'transient'
|
|
| 'volatile'
|
|
| 'strictfp'
|
|
;
|
|
|
|
packageOrTypeName
|
|
: qualifiedName
|
|
;
|
|
|
|
enumConstantName
|
|
: Identifier
|
|
;
|
|
|
|
typeName
|
|
: qualifiedName
|
|
;
|
|
|
|
type
|
|
: classOrInterfaceType ('[' ']')*
|
|
| primitiveType ('[' ']')*
|
|
;
|
|
|
|
classOrInterfaceType
|
|
: Identifier typeArguments? ('.' Identifier typeArguments? )*
|
|
;
|
|
|
|
primitiveType
|
|
: 'boolean'
|
|
| 'char'
|
|
| 'byte'
|
|
| 'short'
|
|
| 'int'
|
|
| 'long'
|
|
| 'float'
|
|
| 'double'
|
|
;
|
|
|
|
variableModifier
|
|
: 'final'
|
|
| annotation
|
|
;
|
|
|
|
typeArguments
|
|
: '<' typeArgument (',' typeArgument)* '>'
|
|
;
|
|
|
|
typeArgument
|
|
: type
|
|
| '?' (('extends' | 'super') type)?
|
|
;
|
|
|
|
qualifiedNameList
|
|
: qualifiedName (',' qualifiedName)*
|
|
;
|
|
|
|
formalParameters
|
|
: '(' formalParameterDecls? ')'
|
|
;
|
|
|
|
formalParameterDecls
|
|
: variableModifiers type formalParameterDeclsRest
|
|
;
|
|
|
|
formalParameterDeclsRest
|
|
: variableDeclaratorId (',' formalParameterDecls)?
|
|
| '...' variableDeclaratorId
|
|
;
|
|
|
|
methodBody
|
|
: block
|
|
;
|
|
|
|
constructorBody
|
|
: '{' explicitConstructorInvocation? blockStatement* '}'
|
|
;
|
|
|
|
explicitConstructorInvocation
|
|
: nonWildcardTypeArguments? ('this' | 'super') arguments ';'
|
|
| primary '.' nonWildcardTypeArguments? 'super' arguments ';'
|
|
;
|
|
|
|
|
|
qualifiedName
|
|
: Identifier ('.' Identifier)*
|
|
;
|
|
|
|
literal
|
|
: integerLiteral
|
|
| FloatingPointLiteral
|
|
| CharacterLiteral
|
|
| StringLiteral
|
|
| booleanLiteral
|
|
| 'null'
|
|
;
|
|
|
|
integerLiteral
|
|
: HexLiteral
|
|
| OctalLiteral
|
|
| DecimalLiteral
|
|
;
|
|
|
|
booleanLiteral
|
|
: 'true'
|
|
| 'false'
|
|
;
|
|
|
|
// ANNOTATIONS
|
|
|
|
annotations
|
|
: annotation+
|
|
;
|
|
|
|
annotation
|
|
: '@' annotationName ( '(' ( elementValuePairs | elementValue )? ')' )?
|
|
;
|
|
|
|
annotationName
|
|
: Identifier ('.' Identifier)*
|
|
;
|
|
|
|
elementValuePairs
|
|
: elementValuePair (',' elementValuePair)*
|
|
;
|
|
|
|
elementValuePair
|
|
: Identifier '=' elementValue
|
|
;
|
|
|
|
elementValue
|
|
: conditionalExpression
|
|
| annotation
|
|
| elementValueArrayInitializer
|
|
;
|
|
|
|
elementValueArrayInitializer
|
|
: '{' (elementValue (',' elementValue)*)? (',')? '}'
|
|
;
|
|
|
|
annotationTypeDeclaration
|
|
: '@' 'interface' Identifier annotationTypeBody
|
|
;
|
|
|
|
annotationTypeBody
|
|
: '{' (annotationTypeElementDeclaration)* '}'
|
|
;
|
|
|
|
annotationTypeElementDeclaration
|
|
: modifiers annotationTypeElementRest
|
|
;
|
|
|
|
annotationTypeElementRest
|
|
: type annotationMethodOrConstantRest ';'
|
|
| normalClassDeclaration ';'?
|
|
| normalInterfaceDeclaration ';'?
|
|
| enumDeclaration ';'?
|
|
| annotationTypeDeclaration ';'?
|
|
;
|
|
|
|
annotationMethodOrConstantRest
|
|
: annotationMethodRest
|
|
| annotationConstantRest
|
|
;
|
|
|
|
annotationMethodRest
|
|
: Identifier '(' ')' defaultValue?
|
|
;
|
|
|
|
annotationConstantRest
|
|
: variableDeclarators
|
|
;
|
|
|
|
defaultValue
|
|
: 'default' elementValue
|
|
;
|
|
|
|
// STATEMENTS / BLOCKS
|
|
|
|
block
|
|
: '{' blockStatement* '}'
|
|
;
|
|
|
|
blockStatement
|
|
: localVariableDeclarationStatement
|
|
| classOrInterfaceDeclaration
|
|
| statement
|
|
;
|
|
|
|
localVariableDeclarationStatement
|
|
: localVariableDeclaration ';'
|
|
;
|
|
|
|
localVariableDeclaration
|
|
: variableModifiers type variableDeclarators
|
|
;
|
|
|
|
variableModifiers
|
|
: variableModifier*
|
|
;
|
|
|
|
statement
|
|
: block
|
|
| ASSERT expression (':' expression)? ';'
|
|
| 'if' parExpression statement (options {k=1;}:'else' statement)?
|
|
| 'for' '(' forControl ')' statement
|
|
| 'while' parExpression statement
|
|
| 'do' statement 'while' parExpression ';'
|
|
| 'try' block
|
|
( catches 'finally' block
|
|
| catches
|
|
| 'finally' block
|
|
)
|
|
| 'switch' parExpression '{' switchBlockStatementGroups '}'
|
|
| 'synchronized' parExpression block
|
|
| 'return' expression? ';'
|
|
| 'throw' expression ';'
|
|
| 'break' Identifier? ';'
|
|
| 'continue' Identifier? ';'
|
|
| ';'
|
|
| statementExpression ';'
|
|
| Identifier ':' statement
|
|
;
|
|
|
|
catches
|
|
: catchClause (catchClause)*
|
|
;
|
|
|
|
catchClause
|
|
: 'catch' '(' formalParameter ')' block
|
|
;
|
|
|
|
formalParameter
|
|
: variableModifiers type variableDeclaratorId
|
|
;
|
|
|
|
switchBlockStatementGroups
|
|
: (switchBlockStatementGroup)*
|
|
;
|
|
|
|
/* 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. */
|
|
switchBlockStatementGroup
|
|
: switchLabel+ blockStatement*
|
|
;
|
|
|
|
switchLabel
|
|
: 'case' constantExpression ':'
|
|
| 'case' enumConstantName ':'
|
|
| 'default' ':'
|
|
;
|
|
|
|
forControl
|
|
options {k=3;} // be efficient for common case: for (ID ID : ID) ...
|
|
: enhancedForControl
|
|
| forInit? ';' expression? ';' forUpdate?
|
|
;
|
|
|
|
forInit
|
|
: localVariableDeclaration
|
|
| expressionList
|
|
;
|
|
|
|
enhancedForControl
|
|
: variableModifiers type Identifier ':' expression
|
|
;
|
|
|
|
forUpdate
|
|
: expressionList
|
|
;
|
|
|
|
// EXPRESSIONS
|
|
|
|
parExpression
|
|
: '(' expression ')'
|
|
;
|
|
|
|
expressionList
|
|
: expression (',' expression)*
|
|
;
|
|
|
|
statementExpression
|
|
: expression
|
|
;
|
|
|
|
constantExpression
|
|
: expression
|
|
;
|
|
|
|
expression
|
|
: conditionalExpression (assignmentOperator expression)?
|
|
;
|
|
|
|
assignmentOperator
|
|
: '='
|
|
| '+='
|
|
| '-='
|
|
| '*='
|
|
| '/='
|
|
| '&='
|
|
| '|='
|
|
| '^='
|
|
| '%='
|
|
| '<' '<' '='
|
|
| '>' '>' '>' '='
|
|
| '>' '>' '='
|
|
/*
|
|
| ('<' '<' '=')=> t1='<' t2='<' t3='='
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() &&
|
|
$t2.getLine() == $t3.getLine() &&
|
|
$t2.getCharPositionInLine() + 1 == $t3.getCharPositionInLine() }?
|
|
| ('>' '>' '>' '=')=> t1='>' t2='>' t3='>' t4='='
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() &&
|
|
$t2.getLine() == $t3.getLine() &&
|
|
$t2.getCharPositionInLine() + 1 == $t3.getCharPositionInLine() &&
|
|
$t3.getLine() == $t4.getLine() &&
|
|
$t3.getCharPositionInLine() + 1 == $t4.getCharPositionInLine() }?
|
|
| ('>' '>' '=')=> t1='>' t2='>' t3='='
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() &&
|
|
$t2.getLine() == $t3.getLine() &&
|
|
$t2.getCharPositionInLine() + 1 == $t3.getCharPositionInLine() }?
|
|
*/
|
|
;
|
|
|
|
conditionalExpression
|
|
: conditionalOrExpression ( '?' conditionalExpression ':' conditionalExpression )?
|
|
;
|
|
|
|
conditionalOrExpression
|
|
: conditionalAndExpression ( '||' conditionalAndExpression )*
|
|
;
|
|
|
|
conditionalAndExpression
|
|
: inclusiveOrExpression ( '&&' inclusiveOrExpression )*
|
|
;
|
|
|
|
inclusiveOrExpression
|
|
: exclusiveOrExpression ( '|' exclusiveOrExpression )*
|
|
;
|
|
|
|
exclusiveOrExpression
|
|
: andExpression ( '^' andExpression )*
|
|
;
|
|
|
|
andExpression
|
|
: equalityExpression ( '&' equalityExpression )*
|
|
;
|
|
|
|
equalityExpression
|
|
: instanceOfExpression ( ('==' | '!=') instanceOfExpression )*
|
|
;
|
|
|
|
instanceOfExpression
|
|
: relationalExpression ('instanceof' type)?
|
|
;
|
|
|
|
relationalExpression
|
|
: shiftExpression ( relationalOp shiftExpression )*
|
|
;
|
|
|
|
relationalOp
|
|
: '<' '='
|
|
| '>' '='
|
|
| '<'
|
|
| '>'
|
|
;
|
|
/*
|
|
relationalOp
|
|
: ('<' '=')=> t1='<' t2='='
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() }?
|
|
| ('>' '=')=> t1='>' t2='='
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() }?
|
|
| '<'
|
|
| '>'
|
|
;
|
|
*/
|
|
|
|
shiftExpression
|
|
: additiveExpression ( shiftOp additiveExpression )*
|
|
;
|
|
|
|
shiftOp
|
|
: '<' '<'
|
|
| '>' '>' '>'
|
|
| '>' '>'
|
|
;
|
|
|
|
/*
|
|
shiftOp
|
|
: ('<' '<')=> t1='<' t2='<'
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() }?
|
|
| ('>' '>' '>')=> t1='>' t2='>' t3='>'
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() &&
|
|
$t2.getLine() == $t3.getLine() &&
|
|
$t2.getCharPositionInLine() + 1 == $t3.getCharPositionInLine() }?
|
|
| ('>' '>')=> t1='>' t2='>'
|
|
{ $t1.getLine() == $t2.getLine() &&
|
|
$t1.getCharPositionInLine() + 1 == $t2.getCharPositionInLine() }?
|
|
;
|
|
*/
|
|
|
|
additiveExpression
|
|
: multiplicativeExpression ( ('+' | '-') multiplicativeExpression )*
|
|
;
|
|
|
|
multiplicativeExpression
|
|
: unaryExpression ( ( '*' | '/' | '%' ) unaryExpression )*
|
|
;
|
|
|
|
unaryExpression
|
|
: '+' unaryExpression
|
|
| '-' unaryExpression
|
|
| '++' unaryExpression
|
|
| '--' unaryExpression
|
|
| unaryExpressionNotPlusMinus
|
|
;
|
|
|
|
unaryExpressionNotPlusMinus
|
|
: '~' unaryExpression
|
|
| '!' unaryExpression
|
|
| castExpression
|
|
| primary selector* ('++'|'--')?
|
|
;
|
|
|
|
castExpression
|
|
: '(' primitiveType ')' unaryExpression
|
|
| '(' (type | expression) ')' unaryExpressionNotPlusMinus
|
|
;
|
|
|
|
primary
|
|
: parExpression
|
|
| 'this' ('.' Identifier)* identifierSuffix?
|
|
| 'super' superSuffix
|
|
| literal
|
|
| 'new' creator
|
|
| Identifier ('.' Identifier)* identifierSuffix?
|
|
| primitiveType ('[' ']')* '.' 'class'
|
|
| 'void' '.' 'class'
|
|
;
|
|
|
|
identifierSuffix
|
|
: ('[' ']')+ '.' 'class'
|
|
| ('[' expression ']')+ // can also be matched by selector, but do here
|
|
| arguments
|
|
| '.' 'class'
|
|
| '.' explicitGenericInvocation
|
|
| '.' 'this'
|
|
| '.' 'super' arguments
|
|
| '.' 'new' innerCreator
|
|
;
|
|
|
|
creator
|
|
: nonWildcardTypeArguments createdName classCreatorRest
|
|
| createdName (arrayCreatorRest | classCreatorRest)
|
|
;
|
|
|
|
createdName
|
|
: classOrInterfaceType
|
|
| primitiveType
|
|
;
|
|
|
|
innerCreator
|
|
: nonWildcardTypeArguments? Identifier classCreatorRest
|
|
;
|
|
|
|
arrayCreatorRest
|
|
: '['
|
|
( ']' ('[' ']')* arrayInitializer
|
|
| expression ']' ('[' expression ']')* ('[' ']')*
|
|
)
|
|
;
|
|
|
|
classCreatorRest
|
|
: arguments classBody?
|
|
;
|
|
|
|
explicitGenericInvocation
|
|
: nonWildcardTypeArguments Identifier arguments
|
|
;
|
|
|
|
nonWildcardTypeArguments
|
|
: '<' typeList '>'
|
|
;
|
|
|
|
selector
|
|
: '.' Identifier arguments?
|
|
| '.' 'this'
|
|
| '.' 'super' superSuffix
|
|
| '.' 'new' innerCreator
|
|
| '[' expression ']'
|
|
;
|
|
|
|
superSuffix
|
|
: arguments
|
|
| '.' Identifier arguments?
|
|
;
|
|
|
|
arguments
|
|
: '(' expressionList? ')'
|
|
;
|
|
|