📄 java.g
字号:
// 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 | "for"^ LPAREN! forInit SEMI! // initializer forCond SEMI! // condition test forIter // updater RPAREN! statement // statement to loop over // While statement | "while"^ LPAREN! expression RPAREN! statement // do-while statement | "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 // empty statement | s:SEMI {#s->setType(EMPTY_STAT);} ;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 { warnWhenFollowAmbig = false; } : aCase )+ caseSList {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);} ;aCase : ("case"^ expression | "default") COLON! ;caseSList : (statement)* {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} ;// The initializer for a for loopforInit // if it looks like a declaration, it is : ( (declaration)=> declaration // otherwise it could be an expression list... | expressionList )? {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);} ;forCond : (expression)? {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);} ;forIter : (expressionList)? {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);} ;// an exception handler try/catch blocktryBlock : "try"^ compoundStatement (handler)* ( "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 : assignmentExpression {#expression = #(#[EXPR,"EXPR"],#expression);} ;// This is a list of expressions.expressionList : expression (COMMA! expression)* {#expressionList = #(#[ELIST,"ELIST"], 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^ conditionalExpression 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 )* ;// 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 : castExpression ((STAR^ | DIV^ | MOD^ ) castExpression)* ;// cast/unary (level 1)castExpression // if it _looks_ like a cast, it _is_ a cast : ( LPAREN typeSpec[true] RPAREN castExpression )=> lp:LPAREN^ {#lp->setType(TYPECAST);} typeSpec[true] RPAREN! c:castExpression // otherwise it's a unary expression | INC^ castExpression | DEC^ castExpression | MINUS^ {#MINUS->setType(UNARY_MINUS);} castExpression | PLUS^ {#PLUS->setType(UNARY_PLUS);} castExpression | BNOT^ castExpression | LNOT^ castExpression | postfixExpression ( "instanceof"^ typeSpec[true] )? // instanceof should not allow just primitives (x instanceof int) // need a semantic check if we're compiling... ;// qualified names, array expressions, method invocation, post inc/decpostfixExpression : primaryExpression // start with a primary ( // qualified id (id.id.id.id...) -- build the name DOT^ ( IDENT | "this" | "class" | newExpression | "super" LPAREN ( expressionList )? RPAREN ) // the above line needs a semantic check to make sure "class" // is the _last_ qualifier. // an array indexing operation | lb:LBRACK^ {#lb->setType(INDEX_OP);} expression RBRACK! // method invocation // The next line is not strictly proper; it allows x(3)(4) or // x[2](4) which are not valid in Java. If this grammar were used // to validate a Java program a semantic check would be needed, or // this rule would get really ugly... | lp:LPAREN^ {#lp->setType(METHOD_CALL);} argList RPAREN! )* // possibly add on a post-increment or post-decrement ( in:INC^ {#in->setType(POST_INC);} | de:DEC^ {#de->setType(POST_DEC);} | // nothing ) ;// the basic element of an expressionprimaryExpression : IDENT | builtInType ( lb:LBRACK^ {#lb->setType(ARRAY_DECLARATOR);} RBRACK! )* DOT^ "class" | newExpression | constant | "super" | "true" | "false" | "this" | "null" | LPAREN! assignmentExpression RPAREN! ;/** object instantiation. * Trees are built as illustrated by the following input/tree pairs: * * new T() * * new * | * T -- ELIST * | * arg1 -- arg2 -- .. -- argn * * new int[] * * new * | * int -- ARRAY_DECLARATOR * * new int[] {1,2} * * new * | * int -- ARRAY_DECLARATOR -- ARRAY_INIT * | * EXPR -- EXPR * | | * 1 2 * * new int[3] * new * | * int -- ARRAY_DECLARATOR * | * EXPR * | * 3 * * new int[1][2] * * new * | * int -- ARRAY_DECLARATOR * | * ARRAY_DECLARATOR -- EXPR * | | * EXPR 1 * | * 2 * */newExpression : "new"^ type ( LPAREN! argList RPAREN! (classBlock)? //java 1.1 // Note: This will allow bad constructs like // new int[4][][3] {exp,exp}. // There needs to be a semantic check here... // to make sure: // a) [ expr ] and [ ] are not mixed // b) [ expr ] and an init are not used together | newArrayDeclarator (arrayInitializer)? ) ;argList : ( expressionList | /*nothing*/ {#argList = #[ELIST,"ELIST"];} ) ;newArrayDeclarator : ( // CONFLICT: // newExpression is a primaryExpression which can be // followed by an array index reference. This is ok, // as the generated code will stay in this loop as // long as it sees an LBRACK (proper behavior) options { warnWhenFollowAmbig = false; } : lb:LBRACK^ {#lb->setType(ARRAY_DECLARATOR);} (expression)? RBRACK! )+ ;constant : NUM_INT | CHAR_LITERAL | STRING_LITERAL | NUM_FLOAT ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -