📄 java.g
字号:
header { package org.drools.semantics.java.parser;}/** Java 1.3 Recognizer. * * This grammar is in the PUBLIC DOMAIN * * @author John Mitchell johnm@non.net * @author Terence Parr parrt@magelang.com * @author John Lilley jlilley@empathy.com * @author Scott Stanchfield thetick@magelang.com * @author Markus Mohnen mohnen@informatik.rwth-aachen.de * @author Peter Williams pete.williams@sun.com * @author Allan Jacobs Allan.Jacobs@eng.sun.com * @author Steve Messick messick@redhills.com * */class JavaRecognizer extends Parser;options { k = 2; // two token lookahead exportVocab=Java; // Call its vocabulary "Java" codeGenMakeSwitchThreshold = 2; // Some optimizations codeGenBitsetTestThreshold = 3; defaultErrorHandler = false; // Don't generate parser error handlers buildAST = true;}tokens { BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF; INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF; PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE; PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP; POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT; IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION; FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract"; STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL; RULE_SET="ruleset"; RULE="rule"; WHEN="when"; THEN="then";} // Compilation Unit: In Java, this is a single file. This is the start// rule for this parsercompilationUnit : // A compilation unit starts with an optional package definition ( packageDefinition | /* nothing */ ) // Next we have a series of zero or more import statements ( importDefinition )* // Wrapping things up with any number of class or interface // definitions ( typeDefinition )* EOF! ;ruleFile : ( packageDefinition | /* nothing */ ) ( importDefinition )* ruleSet ;ruleSet : RULE_SET^ IDENT LCURLY! ( rule )+ RCURLY! ;rule : RULE^ IDENT LPAREN! param:parameterDeclarationList RPAREN! LCURLY! ( parameterDeclaration )* whenBlock thenBlock RCURLY! ;whenBlock : WHEN^ LCURLY! ( ( consistentAssignmentExpression | inclusiveOrExpression ) SEMI! )+ RCURLY! ;thenBlock : THEN^ compoundStatement ;consistentAssignmentExpression : IDENT ASSIGN^ inclusiveOrExpression ;ruleCondition : inclusiveOrExpression ;// consistentAssignmentExpression// | inclusiveOrExpression// Package statement: "package" followed by an identifier.packageDefinition options {defaultErrorHandler = true;} // let ANTLR handle errors : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! ;// Import statement: import followed by a package or class nameimportDefinition options {defaultErrorHandler = true;} : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI! ;// A type definition in a file is either a class or interface definition.typeDefinition options {defaultErrorHandler = true;} : m:modifiers! ( classDefinition[#m] | interfaceDefinition[#m] ) | SEMI! ;/** A declaration is the creation of a reference or primitive-type variable * Create a separate Type/Var tree for each var in the var list. */declaration! : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t] {#declaration = #v;} ;// A type specification is a type name with possible brackets afterwards// (which would make it an array type).typeSpec[boolean addImagNode] : classTypeSpec[addImagNode] | builtInTypeSpec[addImagNode] ;// A class type specification is a class type with possible brackets afterwards// (which would make it an array type).classTypeSpec[boolean addImagNode] : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* { if ( addImagNode ) { #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); } } ;// A builtin type specification is a builtin type with possible brackets// afterwards (which would make it an array type).builtInTypeSpec[boolean addImagNode] : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)* { if ( addImagNode ) { #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); } } ;// A type name. which is either a (possibly qualified) class name or// a primitive (builtin) typetype : identifier | builtInType ;// The primitive types.builtInType : "void" | "boolean" | "byte" | "char" | "short" | "int" | "float" | "long" | "double" ;// A (possibly-qualified) java identifier. We start with the first IDENT// and expand its name by adding dots and following IDENTSidentifier : IDENT ( DOT^ IDENT )* ;identifierStar : 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 : ( modifier )* {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);} ;// modifiers for Java classes, interfaces, class/instance vars and methodsmodifier : "private" | "public" | "protected" | "static" | "transient" | "final" | "abstract" | "native" | "threadsafe" | "synchronized"// | "const" // reserved word, but not valid | "volatile" | "strictfp" ;// Definition of a Java classclassDefinition![AST modifiers] : "class" IDENT // it _might_ have a superclass... sc:superClassClause // it might implement some interfaces... ic:implementsClause // now parse the body of the class cb:classBlock {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"], modifiers,IDENT,sc,ic,cb);} ;superClassClause! : ( "extends" id:identifier )? {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);} ;// Definition of a Java InterfaceinterfaceDefinition![AST modifiers] : "interface" IDENT // it might extend some other interfaces ie:interfaceExtends // now parse the body of the interface (looks like a class...) cb:classBlock {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"], modifiers,IDENT,ie,cb);} ;// This is the body of a class. You can have fields and extra semicolons,// That's about it (until you see what a field is...)classBlock : LCURLY! ( field | SEMI! )* RCURLY! {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);} ;// An interface can extend several other interfaces...interfaceExtends : ( e:"extends"! identifier ( COMMA! identifier )* )? {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], #interfaceExtends);} ;// A class can implement several interfaces...implementsClause : ( i:"implements"! identifier ( COMMA! identifier )* )? {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], #implementsClause);} ;// Now the various things that can be defined inside a class or interface...// Note that not all of these are really valid in an interface (constructors,// for example), and if this grammar were used for a compiler there would// need to be some semantic checks to make sure we're doing the right thing...field! : // method, constructor, or variable declaration mods:modifiers ( h:ctorHead s:constructorBody // constructor {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);} | cd:classDefinition[#mods] // inner class {#field = #cd;} | id:interfaceDefinition[#mods] // inner interface {#field = #id;} | 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 ) {#field = #(#[METHOD_DEF,"METHOD_DEF"], mods, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);} {#field = #v;} ) ) // "static { ... }" class initializer | "static" s3:compoundStatement {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);} // "{ ... }" instance initializer | s4:compoundStatement {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ;constructorBody : lc:LCURLY^ {#lc.setType(SLIST);} // Predicate might be slow but only checked once per constructor def // not for general methods. ( (explicitConstructorInvocation) => explicitConstructorInvocation | ) (statement)* RCURLY! ;explicitConstructorInvocation : ( options { // this/super can begin a primaryExpression too; with finite // lookahead ANTLR will think the 3rd alternative conflicts // with 1, 2. I am shutting off warning since ANTLR resolves // the nondeterminism by correctly matching alts 1 or 2 when // it sees this( or super( generateAmbigWarnings=false; } : "this"! lp1:LPAREN^ argList RPAREN! SEMI! {#lp1.setType(CTOR_CALL);} | "super"! lp2:LPAREN^ argList RPAREN! SEMI! {#lp2.setType(SUPER_CTOR_CALL);} // (new Outer()).super() (create enclosing instance) | primaryExpression DOT! "super"! lp3:LPAREN^ argList RPAREN! SEMI! {#lp3.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] : id:IDENT d:declaratorBrackets[t] v:varInitializer {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],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! // 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 parametersparameterDeclarationList : ( parameterDeclaration ( COMMA! parameterDeclaration )* )? {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"], #parameterDeclarationList);} ;// A formal parameter.parameterDeclaration! : pm:parameterModifier t:typeSpec[false] id:IDENT pd:declaratorBrackets[#t] {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"], pm, #([TYPE,"TYPE"],pd), id);} ;parameterModifier : (f:"final")? {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);} ;// 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! // 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 | "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);} ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -