~repos /gdx-studio
git clone https://pyrossh.dev/repos/gdx-studio.git
An IDE for creating Games using libgdx and Java supported on all platforms Android, iOS, Desktop
src/gdxstudio/parser/Java.g4
/* [The "BSD licence"] Copyright (c) 2013 Terence Parr, Sam Harwell 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.*/
/** A Java 1.7 grammar for ANTLR v4 derived from ANTLR v3 Java grammar. * Uses ANTLR v4's left-recursive expression notation. * It parses ECJ, Netbeans, JDK etc... * * Sam Harwell cleaned this up significantly and updated to 1.7! * * You can test with * * $ antlr4 Java.g4 * $ javac *.java * $ grun Java compilationUnit *.java */grammar Java;
// starting point for parsing a java filecompilationUnit : packageDeclaration? importDeclaration* typeDeclaration* EOF ;
packageDeclaration : annotation* 'package' qualifiedName ';' ;
importDeclaration : 'import' 'static'? qualifiedName ('.' '*')? ';' ;
typeDeclaration : classOrInterfaceModifier* classDeclaration | classOrInterfaceModifier* enumDeclaration | classOrInterfaceModifier* interfaceDeclaration | classOrInterfaceModifier* annotationTypeDeclaration | ';' ;
modifier : classOrInterfaceModifier | ( 'native' | 'synchronized' | 'transient' | 'volatile' ) ;
classOrInterfaceModifier : annotation // class or interface | ( 'public' // class or interface | 'protected' // class or interface | 'private' // class or interface | 'static' // class or interface | 'abstract' // class or interface | 'final' // class only -- does not apply to interfaces | 'strictfp' // class or interface ) ;
variableModifier : 'final' | annotation ;
classDeclaration : 'class' Identifier typeParameters? ('extends' type)? ('implements' typeList)? classBody ;
typeParameters : '<' typeParameter (',' typeParameter)* '>' ;
typeParameter : Identifier ('extends' typeBound)? ;
typeBound : type ('&' type)* ;
enumDeclaration : ENUM Identifier ('implements' typeList)? '{' enumConstants? ','? enumBodyDeclarations? '}' ;
enumConstants : enumConstant (',' enumConstant)* ;
enumConstant : annotation* Identifier arguments? classBody? ;
enumBodyDeclarations : ';' classBodyDeclaration* ;
interfaceDeclaration : 'interface' Identifier typeParameters? ('extends' typeList)? interfaceBody ;
typeList : type (',' type)* ;
classBody : '{' classBodyDeclaration* '}' ;
interfaceBody : '{' interfaceBodyDeclaration* '}' ;
classBodyDeclaration : ';' | 'static'? block | modifier* memberDeclaration ;
memberDeclaration : methodDeclaration | genericMethodDeclaration | fieldDeclaration | constructorDeclaration | genericConstructorDeclaration | interfaceDeclaration | annotationTypeDeclaration | classDeclaration | enumDeclaration ;
/* We use rule this even for void methods which cannot have [] after parameters. This simplifies grammar and we can consider void to be a type, which renders the [] matching as a context-sensitive issue or a semantic check for invalid return type after parsing. */methodDeclaration : (type|'void') Identifier formalParameters ('[' ']')* ('throws' qualifiedNameList)? ( methodBody | ';' ) ;
genericMethodDeclaration : typeParameters methodDeclaration ;
constructorDeclaration : Identifier formalParameters ('throws' qualifiedNameList)? constructorBody ;
genericConstructorDeclaration : typeParameters constructorDeclaration ;
fieldDeclaration : type variableDeclarators ';' ;
interfaceBodyDeclaration : modifier* interfaceMemberDeclaration | ';' ;
interfaceMemberDeclaration : constDeclaration | interfaceMethodDeclaration | genericInterfaceMethodDeclaration | interfaceDeclaration | annotationTypeDeclaration | classDeclaration | enumDeclaration ;
constDeclaration : type constantDeclarator (',' constantDeclarator)* ';' ;
constantDeclarator : Identifier ('[' ']')* '=' variableInitializer ;
// see matching of [] comment in methodDeclaratorRestinterfaceMethodDeclaration : (type|'void') Identifier formalParameters ('[' ']')* ('throws' qualifiedNameList)? ';' ;
genericInterfaceMethodDeclaration : typeParameters interfaceMethodDeclaration ;
variableDeclarators : variableDeclarator (',' variableDeclarator)* ;
variableDeclarator : variableDeclaratorId ('=' variableInitializer)? ;
variableDeclaratorId : Identifier ('[' ']')* ;
variableInitializer : arrayInitializer | expression ;
arrayInitializer : '{' (variableInitializer (',' variableInitializer)* (',')? )? '}' ;
enumConstantName : Identifier ;
type : classOrInterfaceType ('[' ']')* | primitiveType ('[' ']')* ;
classOrInterfaceType : Identifier typeArguments? ('.' Identifier typeArguments? )* ;
primitiveType : 'boolean' | 'char' | 'byte' | 'short' | 'int' | 'long' | 'float' | 'double' ;
typeArguments : '<' typeArgument (',' typeArgument)* '>' ;
typeArgument : type | '?' (('extends' | 'super') type)? ;
qualifiedNameList : qualifiedName (',' qualifiedName)* ;
formalParameters : '(' formalParameterList? ')' ;
formalParameterList : formalParameter (',' formalParameter)* (',' lastFormalParameter)? | lastFormalParameter ;
formalParameter : variableModifier* type variableDeclaratorId ;
lastFormalParameter : variableModifier* type '...' variableDeclaratorId ;
methodBody : block ;
constructorBody : block ;
qualifiedName : Identifier ('.' Identifier)* ;
literal : IntegerLiteral | FloatingPointLiteral | CharacterLiteral | StringLiteral | BooleanLiteral | 'null' ;
// ANNOTATIONS
annotation : '@' annotationName ( '(' ( elementValuePairs | elementValue )? ')' )? ;
annotationName : qualifiedName ;
elementValuePairs : elementValuePair (',' elementValuePair)* ;
elementValuePair : Identifier '=' elementValue ;
elementValue : expression | annotation | elementValueArrayInitializer ;
elementValueArrayInitializer : '{' (elementValue (',' elementValue)*)? (',')? '}' ;
annotationTypeDeclaration : '@' 'interface' Identifier annotationTypeBody ;
annotationTypeBody : '{' (annotationTypeElementDeclaration)* '}' ;
annotationTypeElementDeclaration : modifier* annotationTypeElementRest | ';' // this is not allowed by the grammar, but apparently allowed by the actual compiler ;
annotationTypeElementRest : type annotationMethodOrConstantRest ';' | classDeclaration ';'? | interfaceDeclaration ';'? | enumDeclaration ';'? | annotationTypeDeclaration ';'? ;
annotationMethodOrConstantRest : annotationMethodRest | annotationConstantRest ;
annotationMethodRest : Identifier '(' ')' defaultValue? ;
annotationConstantRest : variableDeclarators ;
defaultValue : 'default' elementValue ;
// STATEMENTS / BLOCKS
block : '{' blockStatement* '}' ;
blockStatement : localVariableDeclarationStatement | statement | typeDeclaration ;
localVariableDeclarationStatement : localVariableDeclaration ';' ;
localVariableDeclaration : variableModifier* type variableDeclarators ;
statement : block | ASSERT expression (':' expression)? ';' | 'if' parExpression statement ('else' statement)? | 'for' '(' forControl ')' statement | 'while' parExpression statement | 'do' statement 'while' parExpression ';' | 'try' block (catchClause+ finallyBlock? | finallyBlock) | 'try' resourceSpecification block catchClause* finallyBlock? | 'switch' parExpression '{' switchBlockStatementGroup* switchLabel* '}' | 'synchronized' parExpression block | 'return' expression? ';' | 'throw' expression ';' | 'break' Identifier? ';' | 'continue' Identifier? ';' | ';' | statementExpression ';' | Identifier ':' statement ;
catchClause : 'catch' '(' variableModifier* catchType Identifier ')' block ;
catchType : qualifiedName ('|' qualifiedName)* ;
finallyBlock : 'finally' block ;
resourceSpecification : '(' resources ';'? ')' ;
resources : resource (';' resource)* ;
resource : variableModifier* classOrInterfaceType variableDeclaratorId '=' expression ;
/** Matches cases then statements, both of which are mandatory. * To handle empty cases at the end, we add switchLabel* to statement. */switchBlockStatementGroup : switchLabel+ blockStatement+ ;
switchLabel : 'case' constantExpression ':' | 'case' enumConstantName ':' | 'default' ':' ;
forControl : enhancedForControl | forInit? ';' expression? ';' forUpdate? ;
forInit : localVariableDeclaration | expressionList ;
enhancedForControl : variableModifier* type variableDeclaratorId ':' expression ;
forUpdate : expressionList ;
// EXPRESSIONS
parExpression : '(' expression ')' ;
expressionList : expression (',' expression)* ;
statementExpression : expression ;
constantExpression : expression ;
expression : primary | expression '.' Identifier | expression '.' 'this' | expression '.' 'new' nonWildcardTypeArguments? innerCreator | expression '.' 'super' superSuffix | expression '.' explicitGenericInvocation | expression '[' expression ']' | expression '(' expressionList? ')' | 'new' creator | '(' type ')' expression | expression ('++' | '--') | ('+'|'-'|'++'|'--') expression | ('~'|'!') expression | expression ('*'|'/'|'%') expression | expression ('+'|'-') expression | expression ('<' '<' | '>' '>' '>' | '>' '>') expression | expression ('<=' | '>=' | '>' | '<') expression | expression 'instanceof' type | expression ('==' | '!=') expression | expression '&' expression | expression '^' expression | expression '|' expression | expression '&&' expression | expression '||' expression | expression '?' expression ':' expression | expression ( '='<assoc=right> | '+='<assoc=right> | '-='<assoc=right> | '*='<assoc=right> | '/='<assoc=right> | '&='<assoc=right> | '|='<assoc=right> | '^='<assoc=right> | '>>='<assoc=right> | '>>>='<assoc=right> | '<<='<assoc=right> | '%='<assoc=right> ) expression ;
primary : '(' expression ')' | 'this' | 'super' | literal | Identifier | type '.' 'class' | 'void' '.' 'class' | nonWildcardTypeArguments (explicitGenericInvocationSuffix | 'this' arguments) ;
creator : nonWildcardTypeArguments createdName classCreatorRest | createdName (arrayCreatorRest | classCreatorRest) ;
createdName : Identifier typeArgumentsOrDiamond? ('.' Identifier typeArgumentsOrDiamond?)* | primitiveType ;
innerCreator : Identifier nonWildcardTypeArgumentsOrDiamond? classCreatorRest ;
arrayCreatorRest : '[' ( ']' ('[' ']')* arrayInitializer | expression ']' ('[' expression ']')* ('[' ']')* ) ;
classCreatorRest : arguments classBody? ;
explicitGenericInvocation : nonWildcardTypeArguments explicitGenericInvocationSuffix ;
nonWildcardTypeArguments : '<' typeList '>' ;
typeArgumentsOrDiamond : '<' '>' | typeArguments ;
nonWildcardTypeArgumentsOrDiamond : '<' '>' | nonWildcardTypeArguments ;
superSuffix : arguments | '.' Identifier arguments? ;
explicitGenericInvocationSuffix : 'super' superSuffix | Identifier arguments ;
arguments : '(' expressionList? ')' ;
// LEXER
// §3.9 Keywords
ABSTRACT : 'abstract';ASSERT : 'assert';BOOLEAN : 'boolean';BREAK : 'break';BYTE : 'byte';CASE : 'case';CATCH : 'catch';CHAR : 'char';CLASS : 'class';CONST : 'const';CONTINUE : 'continue';DEFAULT : 'default';DO : 'do';DOUBLE : 'double';ELSE : 'else';ENUM : 'enum';EXTENDS : 'extends';FINAL : 'final';FINALLY : 'finally';FLOAT : 'float';FOR : 'for';IF : 'if';GOTO : 'goto';IMPLEMENTS : 'implements';IMPORT : 'import';INSTANCEOF : 'instanceof';INT : 'int';INTERFACE : 'interface';LONG : 'long';NATIVE : 'native';NEW : 'new';PACKAGE : 'package';PRIVATE : 'private';PROTECTED : 'protected';PUBLIC : 'public';RETURN : 'return';SHORT : 'short';STATIC : 'static';STRICTFP : 'strictfp';SUPER : 'super';SWITCH : 'switch';SYNCHRONIZED : 'synchronized';THIS : 'this';THROW : 'throw';THROWS : 'throws';TRANSIENT : 'transient';TRY : 'try';VOID : 'void';VOLATILE : 'volatile';WHILE : 'while';
// §3.10.1 Integer Literals
IntegerLiteral : DecimalIntegerLiteral | HexIntegerLiteral | OctalIntegerLiteral | BinaryIntegerLiteral ;
fragmentDecimalIntegerLiteral : DecimalNumeral IntegerTypeSuffix? ;
fragmentHexIntegerLiteral : HexNumeral IntegerTypeSuffix? ;
fragmentOctalIntegerLiteral : OctalNumeral IntegerTypeSuffix? ;
fragmentBinaryIntegerLiteral : BinaryNumeral IntegerTypeSuffix? ;
fragmentIntegerTypeSuffix : [lL] ;
fragmentDecimalNumeral : '0' | NonZeroDigit (Digits? | Underscores Digits) ;
fragmentDigits : Digit (DigitOrUnderscore* Digit)? ;
fragmentDigit : '0' | NonZeroDigit ;
fragmentNonZeroDigit : [1-9] ;
fragmentDigitOrUnderscore : Digit | '_' ;
fragmentUnderscores : '_'+ ;
fragmentHexNumeral : '0' [xX] HexDigits ;
fragmentHexDigits : HexDigit (HexDigitOrUnderscore* HexDigit)? ;
fragmentHexDigit : [0-9a-fA-F] ;
fragmentHexDigitOrUnderscore : HexDigit | '_' ;
fragmentOctalNumeral : '0' Underscores? OctalDigits ;
fragmentOctalDigits : OctalDigit (OctalDigitOrUnderscore* OctalDigit)? ;
fragmentOctalDigit : [0-7] ;
fragmentOctalDigitOrUnderscore : OctalDigit | '_' ;
fragmentBinaryNumeral : '0' [bB] BinaryDigits ;
fragmentBinaryDigits : BinaryDigit (BinaryDigitOrUnderscore* BinaryDigit)? ;
fragmentBinaryDigit : [01] ;
fragmentBinaryDigitOrUnderscore : BinaryDigit | '_' ;
// §3.10.2 Floating-Point Literals
FloatingPointLiteral : DecimalFloatingPointLiteral | HexadecimalFloatingPointLiteral ;
fragmentDecimalFloatingPointLiteral : Digits '.' Digits? ExponentPart? FloatTypeSuffix? | '.' Digits ExponentPart? FloatTypeSuffix? | Digits ExponentPart FloatTypeSuffix? | Digits FloatTypeSuffix ;
fragmentExponentPart : ExponentIndicator SignedInteger ;
fragmentExponentIndicator : [eE] ;
fragmentSignedInteger : Sign? Digits ;
fragmentSign : [+-] ;
fragmentFloatTypeSuffix : [fFdD] ;
fragmentHexadecimalFloatingPointLiteral : HexSignificand BinaryExponent FloatTypeSuffix? ;
fragmentHexSignificand : HexNumeral '.'? | '0' [xX] HexDigits? '.' HexDigits ;
fragmentBinaryExponent : BinaryExponentIndicator SignedInteger ;
fragmentBinaryExponentIndicator : [pP] ;
// §3.10.3 Boolean Literals
BooleanLiteral : 'true' | 'false' ;
// §3.10.4 Character Literals
CharacterLiteral : '\'' SingleCharacter '\'' | '\'' EscapeSequence '\'' ;
fragmentSingleCharacter : ~['\\] ;
// §3.10.5 String Literals
StringLiteral : '"' StringCharacters? '"' ;
fragmentStringCharacters : StringCharacter+ ;
fragmentStringCharacter : ~["\\] | EscapeSequence ;
// §3.10.6 Escape Sequences for Character and String Literals
fragmentEscapeSequence : '\\' [btnfr"'\\] | OctalEscape | UnicodeEscape ;
fragmentOctalEscape : '\\' OctalDigit | '\\' OctalDigit OctalDigit | '\\' ZeroToThree OctalDigit OctalDigit ;
fragmentUnicodeEscape : '\\' 'u' HexDigit HexDigit HexDigit HexDigit ;
fragmentZeroToThree : [0-3] ;
// §3.10.7 The Null Literal
NullLiteral : 'null' ;
// §3.11 Separators
LPAREN : '(';RPAREN : ')';LBRACE : '{';RBRACE : '}';LBRACK : '[';RBRACK : ']';SEMI : ';';COMMA : ',';DOT : '.';
// §3.12 Operators
ASSIGN : '=';GT : '>';LT : '<';BANG : '!';TILDE : '~';QUESTION : '?';COLON : ':';EQUAL : '==';LE : '<=';GE : '>=';NOTEQUAL : '!=';AND : '&&';OR : '||';INC : '++';DEC : '--';ADD : '+';SUB : '-';MUL : '*';DIV : '/';BITAND : '&';BITOR : '|';CARET : '^';MOD : '%';
ADD_ASSIGN : '+=';SUB_ASSIGN : '-=';MUL_ASSIGN : '*=';DIV_ASSIGN : '/=';AND_ASSIGN : '&=';OR_ASSIGN : '|=';XOR_ASSIGN : '^=';MOD_ASSIGN : '%=';LSHIFT_ASSIGN : '<<=';RSHIFT_ASSIGN : '>>=';URSHIFT_ASSIGN : '>>>=';
// §3.8 Identifiers (must appear after all keywords in the grammar)
Identifier : JavaLetter JavaLetterOrDigit* ;
fragmentJavaLetter : [a-zA-Z$_] // these are the "java letters" below 0xFF | // covers all characters above 0xFF which are not a surrogate ~[\u0000-\u00FF\uD800-\uDBFF] {Character.isJavaIdentifierStart(_input.LA(-1))}? | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF [\uD800-\uDBFF] [\uDC00-\uDFFF] {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? ;
fragmentJavaLetterOrDigit : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0xFF | // covers all characters above 0xFF which are not a surrogate ~[\u0000-\u00FF\uD800-\uDBFF] {Character.isJavaIdentifierPart(_input.LA(-1))}? | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF [\uD800-\uDBFF] [\uDC00-\uDFFF] {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? ;
//// Additional symbols not defined in the lexical specification//
AT : '@';ELLIPSIS : '...';
//// Whitespace and comments//
WS : [ \t\r\n\u000C]+ -> skip ;
COMMENT : '/*' .*? '*/' -> skip ;
LINE_COMMENT : '//' ~[\r\n]* -> skip ;