📄 groovy.g
字号:
{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 afterwardsbuiltInTypeArraySpec[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) typetype : 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 IDENTSidentifier : 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 methodsmodifier : "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 classclassDefinition![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 InterfaceinterfaceDefinition![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 classenumBlock {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);} ;/** Guard for enumConstants. */enumConstantsStart : enumConstant (COMMA | SEMI | NLS | RCURLY) ;/** Comma-separated list of one or more enum constant definitions. */enumConstants : enumConstant ( options{greedy=true;}: COMMA! nls! enumConstant )* ( COMMA! nls! )? // trailing extra comma is OK ;// An annotation field
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -