📄 java.g
字号:
// get the list of exceptions that this method is declared to throw (throwsClause)? ;// This is a list of exception classes that the method is declared to throwthrowsClause : "throws"^ identifier ( COMMA! identifier )* ;// A list of formal parameters// Zero or more parameters// If a parameter is variable length (e.g. String... myArg) it is the right-most parameterparameterDeclarationList {Token first = LT(1);} // The semantic check in ( .... )* block is flagged as superfluous, and seems superfluous but // is the only way I could make this work. If my understanding is correct this is a known bug : ( ( parameterDeclaration )=> parameterDeclaration ( options {warnWhenFollowAmbig=false;} : ( COMMA! parameterDeclaration ) => COMMA! parameterDeclaration )* ( COMMA! variableLengthParameterDeclaration )? | variableLengthParameterDeclaration )? {#parameterDeclarationList = #(create(PARAMETERS,"PARAMETERS",first,LT(1)), #parameterDeclarationList);} ;// A formal parameter.parameterDeclaration! {Token first = LT(1);} : pm:parameterModifier t:typeSpec[false] id:IDENT pd:declaratorBrackets[#t] {#parameterDeclaration = #(create(PARAMETER_DEF,"PARAMETER_DEF",first,LT(1)), pm, #(create(TYPE,"TYPE",first,LT(1)),pd), id);} ;variableLengthParameterDeclaration! {Token first = LT(1);} : pm:parameterModifier t:typeSpec[false] TRIPLE_DOT! id:IDENT pd:declaratorBrackets[#t] {#variableLengthParameterDeclaration = #(create(VARIABLE_PARAMETER_DEF,"VARIABLE_PARAMETER_DEF",first,LT(1)), pm, #(create(TYPE,"TYPE",first,LT(1)),pd), id);} ;parameterModifier {Token first = LT(1);} //final can appear amongst annotations in any order - greedily consume any preceding //annotations to shut nond-eterminism warnings off : (options{greedy=true;} : annotation)* (f:"final")? (annotation)* {#parameterModifier = #(create(MODIFIERS,"MODIFIERS",first,LT(1)), #parameterModifier);} ;// Compound statement. This is used in many contexts:// Inside a class definition prefixed with "static":// it is a class initializer// Inside a class definition without "static":// it is an instance initializer// As the body of a method// As a completely indepdent braced block of code inside a method// it starts a new scope for variable definitionscompoundStatement : lc:LCURLY^ {#lc.setType(SLIST);} // include the (possibly-empty) list of statements (statement)* RCURLY! ;statement // A list of statements in curly braces -- start a new scope! : compoundStatement // declarations are ambiguous with "ID DOT" relative to expression // statements. Must backtrack to be sure. Could use a semantic // predicate to test symbol table to see what the type was coming // up, but that's pretty hard without a symbol table ;) | (declaration)=> declaration SEMI! // An expression statement. This could be a method call, // assignment statement, or any other expression evaluated for // side-effects. | expression SEMI! //TODO: what abour interfaces, enums and annotations // class definition | m:modifiers! classDefinition[#m] // Attach a label to the front of a statement | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement // If-else statement | "if"^ LPAREN! expression RPAREN! statement ( // CONFLICT: the old "dangling-else" problem... // ANTLR generates proper code matching // as soon as possible. Hush warning. options { warnWhenFollowAmbig = false; } : "else"! statement )? // For statement | forStatement // While statement | "while"^ LPAREN! expression RPAREN! statement // do-while statement//not supported in java2groovy // | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI! // get out of a loop (or switch) | "break"^ (IDENT)? SEMI! // do next iteration of a loop | "continue"^ (IDENT)? SEMI! // Return an expression | "return"^ (expression)? SEMI! // switch/case statement | "switch"^ LPAREN! expression RPAREN! LCURLY! ( casesGroup )* RCURLY! // exception try-catch block | tryBlock // throw an exception | "throw"^ expression SEMI! // synchronize a statement | "synchronized"^ LPAREN! expression RPAREN! compoundStatement // asserts (uncomment if you want 1.4 compatibility) | "assert"^ expression ( COLON! expression )? SEMI! // empty statement | s:SEMI {#s.setType(EMPTY_STAT);} ;forStatement : f:"for"^ LPAREN! ( (forInit SEMI)=>traditionalForClause | forEachClause ) RPAREN! statement // statement to loop over ;traditionalForClause : forInit SEMI! // initializer forCond SEMI! // condition test forIter // updater ;forEachClause {Token first = LT(1);} : p:parameterDeclaration COLON! expression {#forEachClause = #(create(FOR_EACH_CLAUSE,"FOR_EACH_CLAUSE",first,LT(1)), #forEachClause);} ;casesGroup : ( // CONFLICT: to which case group do the statements bind? // ANTLR generates proper code: it groups the // many "case"/"default" labels together then // follows them with the statements options { greedy = true; } : aCase )+ caseSList {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);} ;aCase : ("case"^ expression | "default") COLON! ;caseSList {Token first = LT(1);} : (statement)* {#caseSList = #(create(SLIST,"SLIST",first,LT(1)),#caseSList);} ;// The initializer for a for loopforInit {Token first = LT(1);} // if it looks like a declaration, it is : ((declaration)=> declaration // otherwise it could be an expression list... | expressionList )? {#forInit = #(create(FOR_INIT,"FOR_INIT",first,LT(1)),#forInit);} ;forCond {Token first = LT(1);} : (expression)? {#forCond = #(create(FOR_CONDITION,"FOR_CONDITION",first,LT(1)),#forCond);} ;forIter {Token first = LT(1);} : (expressionList)? {#forIter = #(create(FOR_ITERATOR,"FOR_ITERATOR",first,LT(1)),#forIter);} ;// an exception handler try/catch blocktryBlock : "try"^ compoundStatement (handler)* ( finallyClause )? ;finallyClause : "finally"^ compoundStatement ;// an exception handlerhandler : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement ;// expressions// Note that most of these expressions follow the pattern// thisLevelExpression :// nextHigherPrecedenceExpression// (OPERATOR nextHigherPrecedenceExpression)*// which is a standard recursive definition for a parsing an expression.// The operators in java have the following precedences:// lowest (13) = *= /= %= += -= <<= >>= >>>= &= ^= |=// (12) ?:// (11) ||// (10) &&// ( 9) |// ( 8) ^// ( 7) &// ( 6) == !=// ( 5) < <= > >=// ( 4) << >>// ( 3) +(binary) -(binary)// ( 2) * / %// ( 1) ++ -- +(unary) -(unary) ~ ! (type)// [] () (method call) . (dot -- identifier qualification)// new () (explicit parenthesis)//// the last two are not usually on a precedence chart; I put them in// to point out that new has a higher precedence than '.', so you// can validy use// new Frame().show()//// Note that the above precedence levels map to the rules below...// Once you have a precedence chart, writing the appropriate rules as below// is usually very straightfoward// the mother of all expressionsexpression {Token first = LT(1);} : assignmentExpression {#expression = #(create(EXPR,"EXPR",first,LT(1)),#expression);} ;// This is a list of expressions.expressionList {Token first = LT(1);} : expression (COMMA! expression)* {#expressionList = #(create(ELIST,"ELIST",first,LT(1)), #expressionList);} ;// assignment expression (level 13)assignmentExpression : conditionalExpression ( ( ASSIGN^ | PLUS_ASSIGN^ | MINUS_ASSIGN^ | STAR_ASSIGN^ | DIV_ASSIGN^ | MOD_ASSIGN^ | SR_ASSIGN^ | BSR_ASSIGN^ | SL_ASSIGN^ | BAND_ASSIGN^ | BXOR_ASSIGN^ | BOR_ASSIGN^ ) assignmentExpression )? ;// conditional test (level 12)conditionalExpression : logicalOrExpression ( QUESTION^ assignmentExpression COLON! conditionalExpression )? ;// logical or (||) (level 11)logicalOrExpression : logicalAndExpression (LOR^ logicalAndExpression)* ;// logical and (&&) (level 10)logicalAndExpression : inclusiveOrExpression (LAND^ inclusiveOrExpression)* ;// bitwise or non-short-circuiting or (|) (level 9)inclusiveOrExpression : exclusiveOrExpression (BOR^ exclusiveOrExpression)* ;// exclusive or (^) (level 8)exclusiveOrExpression : andExpression (BXOR^ andExpression)* ;// bitwise or non-short-circuiting and (&) (level 7)andExpression : equalityExpression (BAND^ equalityExpression)* ;// equality/inequality (==/!=) (level 6)equalityExpression : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)* ;// boolean relational expressions (level 5)relationalExpression : shiftExpression ( ( ( LT^ | GT^ | LE^ | GE^ ) shiftExpression )* | "instanceof"^ typeSpec[true] ) ;// bit shift expressions (level 4)shiftExpression : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)* ;// binary addition/subtraction (level 3)additiveExpression : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)* ;// multiplication/division/modulo (level 2)multiplicativeExpression : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)* ;unaryExpression : INC^ unaryExpression | DEC^ unaryExpression | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression | unaryExpressionNotPlusMinus ;unaryExpressionNotPlusMinus : BNOT^ unaryExpression | LNOT^ unaryExpression | ( // subrule allows option to shut off warnings options { // "(int" ambig with postfixExpr due to lack of sequence // info in linear approximate LL(k). It's ok. Shut up. generateAmbigWarnings=false; } : // If typecast is built in type, must be numeric operand // Have to backtrack to see if operator follows (LPAREN builtInTypeSpec[true] RPAREN unaryExpression)=> lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN! unaryExpression // Have to backtrack to see if operator follows. If no operator // follows, it's a typecast. No semantic checking needed to parse. // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)" | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=> lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN! unaryExpressionNotPlusMinus | postfixExpression ) ;// qualified names, array expressions, method invocation, post inc/decpostfixExpression : primaryExpression ( /* options { // the use of postfixExpression in SUPER_CTOR_CALL adds DOT // to the lookahead set, and gives loads of false non-det // warnings. // shut them off. generateAmbigWarnings=false; } : */ //type arguments are only appropriate for a parameterized method/ctor invocations //semantic check may be needed here to ensure that this is the case DOT^ (typeArguments)? ( IDENT ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} argList RPAREN! )? | "super" ( // (new Outer()).super() (create enclosing instance) lp3:LPAREN^ argList RPAREN! {#lp3.setType(SUPER_CTOR_CALL);} | DOT^ (typeArguments)? IDENT ( lps:LPAREN^ {#lps.setType(METHOD_CALL);} argList RPAREN! )? ) ) | DOT^ "this" | DOT^ newExpression | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK! )* ( // possibly add on a post-increment or post-decrement. // allows INC/DEC on too much, but semantics can check in:INC^ {#in.setType(POST_INC);} | de:DEC^ {#de.setType(POST_DEC);} )? ;// the basic element of an expressionprimaryExpression : identPrimary ( options {greedy=true;} : DOT^ "class" )? | constant | "true" | "false" | "null" | newExpression | "this" | "super" | LPAREN! assignmentExpression RPAREN! // look for int.class and int[].class | builtInType ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )* DOT^ "class" ;/** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class, * and a.b.c.class refs. Also this(...) and super(...). Match * this or super. */identPrimary : (ta1:typeArguments!)? IDENT // Syntax for method invocation with type arguments is // <String>foo("blah") ( options { // .ident could match here or in postfixExpression. // We do want to match here. Turn off warning. greedy=true; // This turns the ambiguity warning of the second alternative // off. See below. (The "false" predicate makes it non-issue) warnWhenFollowAmbig=false; } // we have a new nondeterminism because of // typeArguments... only a syntactic predicate will help... // The problem is that this loop here conflicts with // DOT typeArguments "super" in postfixExpression (k=2) // A proper solution would require a lot of refactoring... : (DOT (typeArguments)? IDENT) => DOT^ (ta2:typeArguments!)? IDENT | {false}? // FIXME: this is very ugly but it seems to work...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -