📄 groovy.g
字号:
protected typeArgumentsOrParametersEnd
: GT! {ltCounter-=1;} nls!
| SR! {ltCounter-=2;} nls!
| BSR! {ltCounter-=3;} nls!
;
// Restriction on wildcard types based on super class or derrived class
typeArgumentBounds
{Token first = LT(1);boolean isUpperBounds = false;}
:
( "extends"! {isUpperBounds=true;} | "super"! ) nls! classOrInterfaceType[false] nls!
{
if (isUpperBounds)
{
#typeArgumentBounds = #(create(TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS",first,LT(1)), #typeArgumentBounds);
}
else
{
#typeArgumentBounds = #(create(TYPE_LOWER_BOUNDS,"TYPE_LOWER_BOUNDS",first,LT(1)), #typeArgumentBounds);
}
}
;
// A builtin type array specification is a builtin type with brackets afterwards
builtInTypeArraySpec[boolean addImagNode] {Token first = LT(1);}
: bt:builtInType!
( (LBRACK)=> // require at least one []
declaratorBrackets[#bt]
| {require(false,
"primitive type parameters not allowed here",
"use the corresponding wrapper type, such as Integer for int"
);}
)
{
if ( addImagNode ) {
#builtInTypeArraySpec = #(create(TYPE,"TYPE",first,LT(1)), #builtInTypeArraySpec);
}
}
;
// A builtin type specification is a builtin type with possible brackets
// afterwards (which would make it an array type).
builtInTypeSpec[boolean addImagNode] {Token first = LT(1);}
: bt:builtInType!
declaratorBrackets[#bt]
{
if ( addImagNode ) {
#builtInTypeSpec = #(create(TYPE,"TYPE",first,LT(1)), #builtInTypeSpec);
}
}
;
// A type name. which is either a (possibly qualified and parameterized)
// class name or a primitive (builtin) type
type
: classOrInterfaceType[false]
| builtInType
;
// The primitive types.
builtInType
: "void"
| "boolean"
| "byte"
| "char"
| "short"
| "int"
| "float"
| "long"
| "double"
| "any"
;
// A (possibly-qualified) java identifier. We start with the first IDENT
// and expand its name by adding dots and following IDENTS
identifier
: IDENT
( options { greedy = true; } :
DOT^ nls! IDENT )*
;
identifierStar
: IDENT
( options { greedy = true; } :
DOT^ nls! IDENT )*
( DOT^ nls! STAR
| "as"^ nls! IDENT
)?
;
modifiersInternal
{ int seenDef = 0; }
:
(
// Without this hush, there is a warning that @IDENT and @interface
// can follow modifiersInternal. But how is @IDENT possible after
// modifiersInternal? And how is @interface possible inside modifiersInternal?
// Is there an antlr bug?
options{generateAmbigWarnings=false;}:
// 'def' is an empty modifier, for disambiguating declarations
{seenDef++ == 0}? // do not allow multiple "def" tokens
"def"! nls!
|
// Note: Duplication of modifiers is detected when walking the AST.
modifier nls!
|
{LA(1)==AT && !LT(2).getText().equals("interface")}?
annotation nls!
)+
;
/** A list of one or more modifier, annotation, or "def". */
modifiers {Token first = LT(1);}
: modifiersInternal
{#modifiers = #(create(MODIFIERS, "MODIFIERS",first,LT(1)), #modifiers);}
;
/** A list of zero or more modifiers, annotations, or "def". */
modifiersOpt {Token first = LT(1);}
: (
// See comment above on hushing warnings.
options{generateAmbigWarnings=false;}:
modifiersInternal
)?
{#modifiersOpt = #(create(MODIFIERS, "MODIFIERS",first,LT(1)), #modifiersOpt);}
;
// modifiers for Java classes, interfaces, class/instance vars and methods
modifier
: "private"
| "public"
| "protected"
| "static"
| "transient"
| "final"
| "abstract"
| "native"
| "threadsafe"
| "synchronized"
| "volatile"
| "strictfp"
;
annotation! {Token first = LT(1);}
: AT! i:identifier ( LPAREN! ( args:annotationArguments )? RPAREN! )?
{#annotation = #(create(ANNOTATION,"ANNOTATION",first,LT(1)), i, args);}
;
annotationsOpt {Token first = LT(1);}
: (annotation nls!)*
{#annotationsOpt = #(create(ANNOTATIONS, "ANNOTATIONS", first, LT(1)), #annotationsOpt);}
;
annotationArguments
: annotationMemberValueInitializer | anntotationMemberValuePairs
;
anntotationMemberValuePairs
: annotationMemberValuePair ( COMMA! nls! annotationMemberValuePair )*
;
annotationMemberValuePair! {Token first = LT(1);}
: i:IDENT ASSIGN! nls! v:annotationMemberValueInitializer
{#annotationMemberValuePair = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",first,LT(1)), i, v);}
;
annotationMemberValueInitializer
: conditionalExpression[0] | annotation
;
/*OBS*
// This is an initializer used to set up an annotation member array.
annotationMemberArrayInitializer
: lc:LCURLY^ {#lc.setType(ANNOTATION_ARRAY_INIT);}
( annotationMemberArrayValueInitializer
(
// CONFLICT: does a COMMA after an initializer start a new
// initializer or start the option ',' at end?
// ANTLR generates proper code by matching
// the comma as soon as possible.
options {
warnWhenFollowAmbig = false;
}
:
COMMA! nls! annotationMemberArrayValueInitializer
)*
(COMMA! nls!)?
)?
RCURLY!
;
*OBS*/
// The two things that can initialize an annotation array element are a conditional expression
// and an annotation (nested annotation array initialisers are not valid)
annotationMemberArrayValueInitializer
: conditionalExpression[0]
| annotation nls!
;
superClassClause!
{Token first = LT(1);}
:
( "extends" nls! c:classOrInterfaceType[false] nls! )?
{#superClassClause = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)),c);}
;
// Definition of a Java class
classDefinition![AST modifiers]
{Token first = LT(1);AST prevCurrentClass = currentClass; }
: "class" IDENT nls!
{ currentClass = #IDENT; }
// it _might_ have type paramaters
(tp:typeParameters)?
// it _might_ have a superclass...
sc:superClassClause
// it might implement some interfaces...
ic:implementsClause
// now parse the body of the class
cb:classBlock
{#classDefinition = #(create(CLASS_DEF,"CLASS_DEF",first,LT(1)),
modifiers,IDENT,tp,sc,ic,cb);}
{ currentClass = prevCurrentClass; }
;
//TODO - where has superClassClause! production gone???
// Definition of a Java Interface
interfaceDefinition![AST modifiers] {Token first = LT(1);}
: "interface" IDENT nls!
// it _might_ have type paramaters
(tp:typeParameters)?
// it might extend some other interfaces
ie:interfaceExtends
// now parse the body of the interface (looks like a class...)
ib:interfaceBlock
{#interfaceDefinition = #(create(INTERFACE_DEF,"INTERFACE_DEF",first,LT(1)),
modifiers,IDENT,tp,ie,ib);}
;
enumDefinition![AST modifiers] {Token first = LT(1);}
: "enum" IDENT
// it might implement some interfaces...
ic:implementsClause
// now parse the body of the enum
eb:enumBlock
{#enumDefinition = #(create(ENUM_DEF,"ENUM_DEF",first,LT(1)),
modifiers,IDENT,ic,eb);}
;
annotationDefinition![AST modifiers] {Token first = LT(1);}
: AT "interface" IDENT
// now parse the body of the annotation
ab:annotationBlock
{#annotationDefinition = #(create(ANNOTATION_DEF,"ANNOTATION_DEF",first,LT(1)),
modifiers,IDENT,ab);}
;
typeParameters
{Token first = LT(1);int currentLtLevel = 0;}
:
{currentLtLevel = ltCounter;}
LT! {ltCounter++;} nls!
typeParameter (COMMA! nls! typeParameter)*
nls!
(typeArgumentsOrParametersEnd)?
// make sure we have gobbled up enough '>' characters
// if we are at the "top level" of nested typeArgument productions
{(currentLtLevel != 0) || ltCounter == currentLtLevel}?
{#typeParameters = #(create(TYPE_PARAMETERS, "TYPE_PARAMETERS",first,LT(1)), #typeParameters);}
;
typeParameter {Token first = LT(1);}
:
// I'm pretty sure Antlr generates the right thing here:
(id:IDENT) ( options{generateAmbigWarnings=false;}: typeParameterBounds )?
{#typeParameter = #(create(TYPE_PARAMETER,"TYPE_PARAMETER",first,LT(1)), #typeParameter);}
;
typeParameterBounds {Token first = LT(1);}
:
"extends"! nls! classOrInterfaceType[false]
(BAND! nls! classOrInterfaceType[false])*
{#typeParameterBounds = #(create(TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS",first,LT(1)), #typeParameterBounds);}
;
// This is the body of a class. You can have classFields and extra semicolons.
classBlock {Token first = LT(1);}
: LCURLY!
( classField )? ( sep! ( classField )? )*
RCURLY!
{#classBlock = #(create(OBJBLOCK, "OBJBLOCK",first,LT(1)), #classBlock);}
;
// This is the body of an interface. You can have interfaceField and extra semicolons.
interfaceBlock {Token first = LT(1);}
: LCURLY!
( interfaceField )? ( sep! ( interfaceField )? )*
RCURLY!
{#interfaceBlock = #(create(OBJBLOCK, "OBJBLOCK",first,LT(1)), #interfaceBlock);}
;
// This is the body of an annotation. You can have annotation fields and extra semicolons,
// That's about it (until you see what an annoation field is...)
annotationBlock {Token first = LT(1);}
: LCURLY!
( annotationField )? ( sep! ( annotationField )? )*
RCURLY!
{#annotationBlock = #(create(OBJBLOCK, "OBJBLOCK",first,LT(1)), #annotationBlock);}
;
// This is the body of an enum. You can have zero or more enum constants
// followed by any number of fields like a regular class
enumBlock {Token first = LT(1);}
: LCURLY!
(
// Need a syntactic predicate, since enumConstants
// can start with foo() as well as classField.
// (It's a true ambiguity, visible in the specification.
// To resolve in practice, use "def" before a real method.)
(enumConstantsStart)=> enumConstants
| (classField)?
)
( sep! (classField)? )*
RCURLY!
{#enumBlock = #(create(OBJBLOCK, "OBJBLOCK",first,LT(1)), #enumBlock);}
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -