📄 java.g
字号:
: IDENT ( DOT^ IDENT )* ( DOT^ STAR )? ;// A list of zero or more modifiers. We could have used (modifier)* in// place of a call to modifiers, but I thought it was a good idea to keep// this rule separate so they can easily be collected in a Vector if// someone so desiresmodifiers {Token first = LT(1);} : ( //hush warnings since the semantic check for "@interface" solves the non-determinism options{generateAmbigWarnings=false;}: modifier | //Semantic check that we aren't matching @interface as this is not an annotation //A nicer way to do this would be nice {LA(1)==AT && !LT(2).getText().equals("interface")}? annotation )* {#modifiers = #(create(MODIFIERS, "MODIFIERS",first,LT(1)), #modifiers);} ;// 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);} ;annotations {Token first = LT(1);} : (annotation)* {#annotations = #([ANNOTATIONS, "ANNOTATIONS"], #annotations);} ;annotationArguments : annotationMemberValueInitializer | anntotationMemberValuePairs ;anntotationMemberValuePairs : annotationMemberValuePair ( COMMA! annotationMemberValuePair )* ;annotationMemberValuePair! {Token first = LT(1);} : i:IDENT ASSIGN! v:annotationMemberValueInitializer {#annotationMemberValuePair = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",first,LT(1)), i, v);} ;annotationMemberValueInitializer : conditionalExpression | annotation | annotationMemberArrayInitializer ;// 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! annotationMemberArrayValueInitializer )* (COMMA!)? )? RCURLY! ;// 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 | annotation ;superClassClause! {Token first = LT(1);} : ( "extends" c:classOrInterfaceType[false] )? {#superClassClause = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)),c);} ;// Definition of a Java classclassDefinition![AST modifiers] {Token first = LT(1);} : "class" 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);} ;// Definition of a Java InterfaceinterfaceDefinition![AST modifiers] {Token first = LT(1);} : "interface" IDENT // 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{int currentLtLevel = 0; Token first = LT(1);} : {currentLtLevel = ltCounter;} LT! {ltCounter++;} typeParameter (COMMA! typeParameter)* (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"! classOrInterfaceType[false] (BAND! 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 : LCURLY! ( classField | SEMI! )* RCURLY! {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);} ;// This is the body of an interface. You can have interfaceField and extra semicolons.interfaceBlock : LCURLY! ( interfaceField | SEMI! )* RCURLY! {#interfaceBlock = #([OBJBLOCK, "OBJBLOCK"], #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 : LCURLY! ( annotationField | SEMI! )* RCURLY! {#annotationBlock = #([OBJBLOCK, "OBJBLOCK"], #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 : LCURLY! ( enumConstant ( options{greedy=true;}: COMMA! enumConstant )* ( COMMA! )? )? ( SEMI! ( classField | SEMI! )* )? RCURLY! {#enumBlock = #([OBJBLOCK, "OBJBLOCK"], #enumBlock);} ;// An annotation fieldannotationField! {Token first = LT(1);} : mods:modifiers ( td:typeDefinitionInternal[#mods] {#annotationField = #td;} | t:typeSpec[false] // annotation field ( i:IDENT // the name of the field LPAREN! RPAREN! rt:declaratorBrackets[#t] ( "default" amvi:annotationMemberValueInitializer )? SEMI {#annotationField = #(create(ANNOTATION_FIELD_DEF,"ANNOTATION_FIELD_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)),rt), i,amvi );} | v:variableDefinitions[#mods,#t] SEMI // variable {#annotationField = #v;} ) ) ;//An enum constant may have optional parameters and may have a//a class bodyenumConstant! : an:annotations i:IDENT ( LPAREN! a:argList RPAREN! )? ( b:enumConstantBlock )? {#enumConstant = #([ENUM_CONSTANT_DEF, "ENUM_CONSTANT_DEF"], an, i, a, b);} ;//The class-like body of an enum constantenumConstantBlock : LCURLY! ( enumConstantField | SEMI! )* RCURLY! {#enumConstantBlock = #([OBJBLOCK, "OBJBLOCK"], #enumConstantBlock);} ;//An enum constant field is just like a class field but without//the posibility of a constructor definition or a static initializerenumConstantField! {Token first = LT(1);} : mods:modifiers ( td:typeDefinitionInternal[#mods] {#enumConstantField = #td;} | // A generic method has the typeParameters before the return type. // This is not allowed for variable definitions, but this production // allows it, a semantic check could be used if you wanted. (tp:typeParameters)? t:typeSpec[false] // method or variable declaration(s) ( IDENT // the name of the method // parse the formal parameter declarations. LPAREN! param:parameterDeclarationList RPAREN! rt:declaratorBrackets[#t] // get the list of exceptions that this method is // declared to throw (tc:throwsClause)? ( s2:compoundStatement | SEMI ) {#enumConstantField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)), mods, tp, #(create(TYPE,"TYPE",first,LT(1)),rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#enumConstantField = #v;} ) ) // "{ ... }" instance initializer | s4:compoundStatement {#enumConstantField = #(create(INSTANCE_INIT,"INSTANCE_INIT",first,LT(1)), s4);} ;// An interface can extend several other interfaces...interfaceExtends {Token first = LT(1);} : ( e:"extends"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#interfaceExtends = #(create(EXTENDS_CLAUSE,"EXTENDS_CLAUSE",first,LT(1)), #interfaceExtends);} ;// A class can implement several interfaces...implementsClause {Token first = LT(1);} : ( i:"implements"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#implementsClause = #(create(IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE",first,LT(1)), #implementsClause);} ;// Now the various things that can be defined inside a classclassField! {Token first = LT(1);} : // method, constructor, or variable declaration mods:modifiers ( td:typeDefinitionInternal[#mods] {#classField = #td;} | (tp:typeParameters)? ( h:ctorHead s:constructorBody // constructor // just treat CTOR_DEF like METHOD_DEF for java2groovy {#classField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)), mods, tp, h, s);} | // A generic method/ctor has the typeParameters before the return type. // This is not allowed for variable definitions, but this production // allows it, a semantic check could be used if you wanted. t:typeSpec[false] // method or variable declaration(s) ( IDENT // the name of the method // parse the formal parameter declarations. LPAREN! param:parameterDeclarationList RPAREN! rt:declaratorBrackets[#t] // get the list of exceptions that this method is // declared to throw (tc:throwsClause)? ( s2:compoundStatement | SEMI ) {#classField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)), mods, tp, #(create(TYPE,"TYPE",first,LT(1)),rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#classField = #v;} ) ) ) // "static { ... }" class initializer | "static" s3:compoundStatement {#classField = #(create(STATIC_INIT,"STATIC_INIT",first,LT(1)), s3);} // "{ ... }" instance initializer | s4:compoundStatement {#classField = #(create(INSTANCE_INIT,"INSTANCE_INIT",first,LT(1)), s4);} ;// Now the various things that can be defined inside a interfaceinterfaceField! {Token first = LT(1);} : // method, constructor, or variable declaration mods:modifiers ( td:typeDefinitionInternal[#mods] {#interfaceField = #td;} | (tp:typeParameters)? // A generic method has the typeParameters before the return type. // This is not allowed for variable definitions, but this production // allows it, a semantic check could be used if you want a more strict // grammar. t:typeSpec[false] // method or variable declaration(s) ( IDENT // the name of the method // parse the formal parameter declarations. LPAREN! param:parameterDeclarationList RPAREN! rt:declaratorBrackets[#t] // get the list of exceptions that this method is // declared to throw (tc:throwsClause)? SEMI {#interfaceField = #(create(METHOD_DEF,"METHOD_DEF",first,LT(1)), mods, tp, #(create(TYPE,"TYPE",first,LT(1)),rt), IDENT, param, tc);} | v:variableDefinitions[#mods,#t] SEMI {#interfaceField = #v;} ) ) ;constructorBody : lc:LCURLY^ {#lc.setType(SLIST);} ( options { greedy=true; } : explicitConstructorInvocation)? (statement)* RCURLY! ;/** Catch obvious constructor calls, but not the expr.super(...) calls */explicitConstructorInvocation : (typeArguments)? ( "this"! lp1:LPAREN^ argList RPAREN! SEMI! {#lp1.setType(CTOR_CALL);} | "super"! lp2:LPAREN^ argList RPAREN! SEMI! {#lp2.setType(SUPER_CTOR_CALL);} ) ;variableDefinitions[AST mods, AST t] : variableDeclarator[getASTFactory().dupTree(mods), getASTFactory().dupTree(t)] ( COMMA! variableDeclarator[getASTFactory().dupTree(mods), getASTFactory().dupTree(t)] )* ;/** Declaration of a variable. This can be a class/instance variable, * or a local variable in a method * It can also include possible initialization. */variableDeclarator![AST mods, AST t] { Token first = LT(1);} : id:IDENT d:declaratorBrackets[t] v:varInitializer {#variableDeclarator = #(create(VARIABLE_DEF,"VARIABLE_DEF",first,LT(1)), mods, #(create(TYPE,"TYPE",first,LT(1)),d), id, v);} ;declaratorBrackets[AST typ] : {#declaratorBrackets=typ;} (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* ;varInitializer : ( ASSIGN^ initializer )? ;// This is an initializer used to set up an array./*arrayInitializer : lc:LCURLY^ {#lc.setType(ARRAY_INIT);} ( initializer ( // 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! initializer )* (COMMA!)? )? RCURLY! ;*/// The two "things" that can initialize an array element are an expression// and another (nested) array initializer.initializer : expression// | arrayInitializer ;// This is the header of a method. It includes the name and parameters// for the method.// This also watches for a list of exception classes in a "throws" clause.ctorHead : IDENT // the name of the method // parse the formal parameter declarations. LPAREN! parameterDeclarationList RPAREN!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -