antlr-maven-plugin-2.2/0000775000175000017500000000000012165015352014427 5ustar ebourgebourgantlr-maven-plugin-2.2/pom.xml0000664000175000017500000001301111470606050015737 0ustar ebourgebourg org.codehaus.mojo mojo-parent 27 4.0.0 antlr-maven-plugin 2.2 maven-plugin Maven ANTLR Plugin Maven Plugin for Antlr v2 2004 The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo 2.0.2 scm:svn:http://svn.codehaus.org/mojo/tags/antlr-maven-plugin-2.2 scm:svn:https://svn.codehaus.org/mojo/tags/antlr-maven-plugin-2.2 http://fisheye.codehaus.org/browse/mojo/tags/antlr-maven-plugin-2.2 jira http://jira.codehaus.org/browse/MANTLR vsiveton Vincent Siveton vsiveton@apache.org ASF Java Developer -5 org.apache.maven maven-project 2.0.2 plexus plexus-utils org.apache.maven.reporting maven-reporting-impl 2.0.2 plexus plexus-utils org.apache.maven maven-plugin-api 2.0.2 plexus plexus-utils org.codehaus.plexus plexus-i18n 1.0-beta-6 org.codehaus.plexus plexus-utils 1.4.1 org.apache.maven.wagon wagon-provider-api 1.0-beta-1 org.apache.commons commons-exec 1.0 org.apache.maven.shared maven-plugin-testing-harness 1.1 test org.codehaus.modello modello-maven-plugin 1.0-alpha-8 java 1.0.0 src/main/mdo/antlrOptions.mdo run-its maven.test.skip !true org.apache.maven.plugins maven-invoker-plugin 1.3 true target/it src/it **/pom.xml verify.bsh site ${project.build.directory}/local-repo integration-test integration-test install run antlr-maven-plugin-2.2/src/0000775000175000017500000000000012165015352015216 5ustar ebourgebourgantlr-maven-plugin-2.2/src/site/0000775000175000017500000000000012165015352016162 5ustar ebourgebourgantlr-maven-plugin-2.2/src/site/fml/0000775000175000017500000000000012165015352016740 5ustar ebourgebourgantlr-maven-plugin-2.2/src/site/fml/faq.fml0000664000175000017500000000376210773161441020223 0ustar ebourgebourg Where do I put grammar files?

By default, grammar files should be in the ${basedir}/src/main/antlr directory.

What is the process order of grammar files?

The order is based on the grammar definition. For instance, with the following configuration <grammars>grammar1.g,grammar2.g</grammars>, antlr is called twice, first time with grammar1.g, second time with grammar2.g.

The order is important when grammar files use import vocabulary

Is there any support of Antlr v3?

Use the antlr3-maven-plugin.

antlr-maven-plugin-2.2/src/site/apt/0000775000175000017500000000000012165015352016746 5ustar ebourgebourgantlr-maven-plugin-2.2/src/site/apt/usage.apt.vm0000664000175000017500000000734311470577637021231 0ustar ebourgebourg ------ Usage ------ Vincent Siveton ------ September 2006 ------ ~~ Licensed to the Apache Software Foundation (ASF) under one ~~ or more contributor license agreements. See the NOTICE file ~~ distributed with this work for additional information ~~ regarding copyright ownership. The ASF licenses this file ~~ to you under the Apache License, Version 2.0 (the ~~ "License"); you may not use this file except in compliance ~~ with the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, ~~ software distributed under the License is distributed on an ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~~ KIND, either express or implied. See the License for the ~~ specific language governing permissions and limitations ~~ under the License. ~~ NOTE: For help with the syntax of this file, see: ~~ http://maven.apache.org/doxia/references/apt-format.html Usage The Antlr Plugin generates files based on grammar file(s). The following examples describe the basic usage of the Plugin. * Generate Files From Antlr Grammar File(s) You must configure the Antlr Plugin as follow: +-----+ ... ... org.codehaus.mojo antlr-maven-plugin ${project.version} java.g ... ... +-----+ To generate files, you should execute the generate goal of the Antlr Plugin, i.e.: +-----+ mvn antlr:generate +-----+ * Generate Files From Antlr Grammar File(s) As Part Of Your Build When you compile your project, the Antlr Plugin could be executed. You should add the \ section as follow: +-----+ ... ... org.codehaus.mojo antlr-maven-plugin ${project.version} java.g generate ... ... +-----+ When you execute <<>>, the files will be generated and included in your compile sources. * Generate Antlr Reports To include Antlr reports in your documentation, you must configure the following in the \ section of your pom: +-----+ ... ... org.codehaus.mojo antlr-maven-plugin ${project.version} java15.g ... ... +-----+ When you execute <<>>, the report will be generated. antlr-maven-plugin-2.2/src/site/apt/examples/0000775000175000017500000000000012165015352020564 5ustar ebourgebourgantlr-maven-plugin-2.2/src/site/apt/examples/inheritance.apt.vm0000664000175000017500000000377211470577637024236 0ustar ebourgebourg ------ Grammar Inheritance ------ Vincent Siveton ------ September 2006 ------ ~~ Licensed to the Apache Software Foundation (ASF) under one ~~ or more contributor license agreements. See the NOTICE file ~~ distributed with this work for additional information ~~ regarding copyright ownership. The ASF licenses this file ~~ to you under the Apache License, Version 2.0 (the ~~ "License"); you may not use this file except in compliance ~~ with the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, ~~ software distributed under the License is distributed on an ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~~ KIND, either express or implied. See the License for the ~~ specific language governing permissions and limitations ~~ under the License. ~~ NOTE: For help with the syntax of this file, see: ~~ http://maven.apache.org/doxia/references/apt-format.html Grammar Inheritance To set "supergrammars" available to some grammar, use the \ configuration in your pom: +-----+ ... ... org.codehaus.mojo antlr-maven-plugin ${project.version} StdCParser.g GnuCParser.g StdCParser.g GnuCTreeParser.g GnuCEmitter.g GnuCTreeParser.g ... ... +-----+ antlr-maven-plugin-2.2/src/site/apt/index.apt.vm0000664000175000017500000000651411470577637021233 0ustar ebourgebourg ------ Introduction ------ Vincent Siveton ------ May 2007 ------ ~~ Licensed to the Apache Software Foundation (ASF) under one ~~ or more contributor license agreements. See the NOTICE file ~~ distributed with this work for additional information ~~ regarding copyright ownership. The ASF licenses this file ~~ to you under the Apache License, Version 2.0 (the ~~ "License"); you may not use this file except in compliance ~~ with the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, ~~ software distributed under the License is distributed on an ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~~ KIND, either express or implied. See the License for the ~~ specific language governing permissions and limitations ~~ under the License. ~~ NOTE: For help with the syntax of this file, see: ~~ http://maven.apache.org/doxia/references/apt-format.html ${project.name} The Antlr Plugin uses the parser generator {{{http://www.antlr2.org/}Antlr v2}}. For more information about Antlr v2, please refer to {{{http://www.antlr2.org/doc/index.html}Antlr v2 Reference Manual}}. Refer to {{{./dependencies.html}Project Dependencies}} to know the Antlr version used by the Plugin. <>: This plugin is for <>. For an <>, see the {{{http://mojo.codehaus.org/antlr3-maven-plugin/}antlr3-maven-plugin}}. * Goals Overview The Antlr Plugin has two goals: * {{{./generate-mojo.html}antlr:generate}} Generates file(s) to a target directory based on grammar file(s). * {{{./html-mojo.html}antlr:html}} Generates Antlr report for grammar file(s). * Usage General instructions on how to use the Plugin Name can be found on the {{{./usage.html}usage page}}. Some more specific use cases are described in the examples given below. Last but not least, users occasionally contribute additional examples, tips or errata to the {{{http://docs.codehaus.org/display/MAVENUSER/Antlr+Plugin}plugin's wiki page}}. In case you still have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel free to contact the {{{./mail-lists.html}user mailing list}}. The posts to the mailing list are archived and could already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching the {{{./mail-lists.html}mail archive}}. If you feel like the plugin is missing a feature or has a defect, you can fill a feature request or bug report in our {{{./issue-tracking.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason, entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. Of course, patches are welcome, too. Contributors can check out the project from our {{{./source-repository.html}source repository}} and will find supplementary information in the {{{http://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. * Examples The following examples show how to use the Antlr Plugin in more advanced usecases: * {{{./examples/inheritance.html}Grammar Inheritance}} antlr-maven-plugin-2.2/src/site/site.xml0000664000175000017500000000224511470577637017674 0ustar ebourgebourg antlr-maven-plugin-2.2/src/test/0000775000175000017500000000000012165015351016174 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/0000775000175000017500000000000012165015351020206 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/0000775000175000017500000000000012165015352021166 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/0000775000175000017500000000000012165015352026777 5ustar ebourgebourg././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/java-grammar-inheritance-test-plugin-config.xmlantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/java-grammar-inheritanc0000664000175000017500000000502310773161441033415 0ustar ebourgebourg 4.0.0 java-grammar.test java-grammar-test jar 1.0-SNAPSHOT 2006 Maven Antlr Plugin Java-grammar Test http://mojo.codehaus.org antlr antlr 2.7.7 org.codehaus.mojo antlr-maven-plugin ${basedir}/target/test/unit/java-grammar-inheritance-test/target/generated-sources/antlr ${basedir}/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr StdCParser.g GnuCParser.g StdCParser.g GnuCTreeParser.g GnuCEmitter.g GnuCTreeParser.g antlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/LICENSE.TXT0000664000175000017500000000320610773161441030467 0ustar ebourgebourg Copyright (c) 1998-2000, Non, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by Non, Inc. and its contributors. Neither name of the company nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. antlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/0000775000175000017500000000000012165015352027566 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/0000775000175000017500000000000012165015352030512 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/0000775000175000017500000000000012165015352031632 5ustar ebourgebourg././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/StdCParser.gantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/StdCPars0000664000175000017500000011076610647361554033266 0ustar ebourgebourg/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Copyright (c) Non, Inc. 1997 -- All Rights Reserved PROJECT: C Compiler MODULE: Parser FILE: stdc.g AUTHOR: John D. Mitchell (john@non.net), Jul 12, 1997 REVISION HISTORY: Name Date Description ---- ---- ----------- JDM 97.07.12 Initial version. JTC 97.11.18 Declaration vs declarator & misc. hacking. JDM 97.11.20 Fixed: declaration vs funcDef, parenthesized expressions, declarator iteration, varargs recognition, empty source file recognition, and some typos. DESCRIPTION: This grammar supports the Standard C language. Note clearly that this grammar does *NOT* deal with preprocessor functionality (including things like trigraphs) Nor does this grammar deal with multi-byte characters nor strings containing multi-byte characters [these constructs are "exercises for the reader" as it were :-)]. Please refer to the ISO/ANSI C Language Standard if you believe this grammar to be in error. Please cite chapter and verse in any correspondence to the author to back up your claim. TODO: - typedefName is commented out, needs a symbol table to resolve ambiguity. - trees %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ { import java.io.*; import antlr.CommonAST; import antlr.DumpASTVisitor; } class StdCParser extends Parser; options { k = 2; exportVocab = STDC; buildAST = true; ASTLabelType = "TNode"; // Copied following options from java grammar. codeGenMakeSwitchThreshold = 2; codeGenBitsetTestThreshold = 3; } { // Suppport C++-style single-line comments? public static boolean CPPComments = true; // access to symbol table public CSymbolTable symbolTable = new CSymbolTable(); // source for names to unnamed scopes protected int unnamedScopeCounter = 0; public boolean isTypedefName(String name) { boolean returnValue = false; TNode node = symbolTable.lookupNameInCurrentScope(name); for (; node != null; node = (TNode) node.getNextSibling() ) { if(node.getType() == LITERAL_typedef) { returnValue = true; break; } } return returnValue; } public String getAScopeName() { return "" + (unnamedScopeCounter++); } public void pushScope(String scopeName) { symbolTable.pushScope(scopeName); } public void popScope() { symbolTable.popScope(); } int traceDepth = 0; public void reportError(RecognitionException ex) { try { System.err.println("ANTLR Parsing Error: "+ex + " token name:" + tokenNames[LA(1)]); ex.printStackTrace(System.err); } catch (TokenStreamException e) { System.err.println("ANTLR Parsing Error: "+ex); ex.printStackTrace(System.err); } } public void reportError(String s) { System.err.println("ANTLR Parsing Error from String: " + s); } public void reportWarning(String s) { System.err.println("ANTLR Parsing Warning from String: " + s); } public void match(int t) throws MismatchedTokenException { boolean debugging = false; if ( debugging ) { for (int x=0; x0)?" [inputState.guessing "+ inputState.guessing + "]":"")); } } try { if ( LA(1)!=t ) { if ( debugging ){ for (int x=0; x "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()] + ") " + LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]"); } catch (TokenStreamException e) { } } public void traceOut(String rname) { for (int x=0; x declaration | functionDef | asm_expr ; asm_expr : "asm"^ ("volatile")? LCURLY! expr RCURLY! SEMI! ; declaration { AST ds1 = null; } : ds:declSpecifiers { ds1 = astFactory.dupList(#ds); } ( initDeclList[ds1] )? SEMI! { ## = #( #[NDeclaration], ##); } ; declSpecifiers { int specCount=0; } : ( options { // this loop properly aborts when // it finds a non-typedefName ID MBZ warnWhenFollowAmbig = false; } : s:storageClassSpecifier | typeQualifier | ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> specCount = typeSpecifier[specCount] )+ ; storageClassSpecifier : "auto" | "register" | "typedef" | functionStorageClassSpecifier ; functionStorageClassSpecifier : "extern" | "static" ; typeQualifier : "const" | "volatile" ; typeSpecifier [int specCount] returns [int retSpecCount] { retSpecCount = specCount + 1; } : ( "void" | "char" | "short" | "int" | "long" | "float" | "double" | "signed" | "unsigned" | structOrUnionSpecifier | enumSpecifier | { specCount == 0 }? typedefName ) ; typedefName : { isTypedefName ( LT(1).getText() ) }? i:ID { ## = #(#[NTypedefName], #i); } ; structOrUnionSpecifier { String scopeName; } : sou:structOrUnion! ( ( ID LCURLY )=> i:ID l:LCURLY { scopeName = #sou.getText() + " " + #i.getText(); #l.setText(scopeName); pushScope(scopeName); } structDeclarationList { popScope();} RCURLY! | l1:LCURLY { scopeName = getAScopeName(); #l1.setText(scopeName); pushScope(scopeName); } structDeclarationList { popScope(); } RCURLY! | ID ) { ## = #( #sou, ## ); } ; structOrUnion : "struct" | "union" ; structDeclarationList : ( structDeclaration )+ ; structDeclaration : specifierQualifierList structDeclaratorList ( SEMI! )+ ; specifierQualifierList { int specCount = 0; } : ( options { // this loop properly aborts when // it finds a non-typedefName ID MBZ warnWhenFollowAmbig = false; } : ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> specCount = typeSpecifier[specCount] | typeQualifier )+ ; structDeclaratorList : structDeclarator ( COMMA! structDeclarator )* ; structDeclarator : ( COLON constExpr | declarator[false] ( COLON constExpr )? ) { ## = #( #[NStructDeclarator], ##); } ; enumSpecifier : "enum"^ ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY! | LCURLY enumList["anonymous"] RCURLY! | ID ) ; enumList[String enumName] : enumerator[enumName] ( COMMA! enumerator[enumName] )* ; enumerator[String enumName] : i:ID { symbolTable.add( i.getText(), #( null, #[LITERAL_enum, "enum"], #[ ID, enumName] ) ); } (ASSIGN constExpr)? ; initDeclList[AST declarationSpecifiers] : initDecl[declarationSpecifiers] ( COMMA! initDecl[declarationSpecifiers] )* ; initDecl[AST declarationSpecifiers] { String declName = ""; } : declName = d:declarator[false] { AST ds1, d1; ds1 = astFactory.dupList(declarationSpecifiers); d1 = astFactory.dupList(#d); symbolTable.add(declName, #(null, ds1, d1) ); } ( ASSIGN initializer | COLON expr )? { ## = #( #[NInitDecl], ## ); } ; pointerGroup : ( STAR ( typeQualifier )* )+ { ## = #( #[NPointerGroup], ##); } ; idList : ID ( COMMA! ID )* ; initializer : ( assignExpr | LCURLY initializerList ( COMMA! )? RCURLY! ) { ## = #( #[NInitializer], ## ); } ; initializerList : initializer ( COMMA! initializer )* ; declarator[boolean isFunctionDefinition] returns [String declName] { declName = ""; } : ( pointerGroup )? ( id:ID { declName = id.getText(); } | LPAREN declName = declarator[false] RPAREN ) ( ! LPAREN { if (isFunctionDefinition) { pushScope(declName); } else { pushScope("!"+declName); } } ( (declSpecifiers)=> p:parameterTypeList { ## = #( null, ##, #( #[NParameterTypeList], #p ) ); } | (i:idList)? { ## = #( null, ##, #( #[NParameterTypeList], #i ) ); } ) { popScope(); } RPAREN | LBRACKET ( constExpr )? RBRACKET )* { ## = #( #[NDeclarator], ## ); } ; parameterTypeList : parameterDeclaration ( options { warnWhenFollowAmbig = false; } : COMMA! parameterDeclaration )* ( COMMA! VARARGS )? ; parameterDeclaration { String declName; } : ds:declSpecifiers ( ( declarator[false] )=> declName = d:declarator[false] { AST d2, ds2; d2 = astFactory.dupList(#d); ds2 = astFactory.dupList(#ds); symbolTable.add(declName, #(null, ds2, d2)); } | nonemptyAbstractDeclarator )? { ## = #( #[NParameterDeclaration], ## ); } ; /* JTC: * This handles both new and old style functions. * see declarator rule to see differences in parameters * and here (declaration SEMI)* is the param type decls for the * old style. may want to do some checking to check for illegal * combinations (but I assume all parsed code will be legal?) */ functionDef { String declName; } : ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers | //epsilon ) declName = d:declarator[true] { AST d2, ds2; d2 = astFactory.dupList(#d); ds2 = astFactory.dupList(#ds); symbolTable.add(declName, #(null, ds2, d2)); pushScope(declName); } ( declaration )* (VARARGS)? ( SEMI! )* { popScope(); } compoundStatement[declName] { ## = #( #[NFunctionDef], ## );} ; functionDeclSpecifiers { int specCount = 0; } : ( options { // this loop properly aborts when // it finds a non-typedefName ID MBZ warnWhenFollowAmbig = false; } : functionStorageClassSpecifier | typeQualifier | ( "struct" | "union" | "enum" | typeSpecifier[specCount] )=> specCount = typeSpecifier[specCount] )+ ; declarationList : ( options { // this loop properly aborts when // it finds a non-typedefName ID MBZ warnWhenFollowAmbig = false; } : ( declarationPredictor )=> declaration )+ ; declarationPredictor : (options { //only want to look at declaration if I don't see typedef warnWhenFollowAmbig = false; }: "typedef" | declaration ) ; compoundStatement[String scopeName] : LCURLY! { pushScope(scopeName); } ( ( declarationPredictor)=> declarationList )? ( statementList )? { popScope(); } RCURLY! { ## = #( #[NCompoundStatement, scopeName], ##); } ; statementList : ( statement )+ ; statement : SEMI // Empty statements | compoundStatement[getAScopeName()] // Group of statements | expr SEMI! { ## = #( #[NStatementExpr], ## ); } // Expressions // Iteration statements: | "while"^ LPAREN! expr RPAREN! statement | "do"^ statement "while"! LPAREN! expr RPAREN! SEMI! |! "for" LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN s:statement { if ( #e1 == null) { #e1 = #[ NEmptyExpression ]; } if ( #e2 == null) { #e2 = #[ NEmptyExpression ]; } if ( #e3 == null) { #e3 = #[ NEmptyExpression ]; } ## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s ); } // Jump statements: | "goto"^ ID SEMI! | "continue" SEMI! | "break" SEMI! | "return"^ ( expr )? SEMI! // Labeled statements: | ID COLON! (options {warnWhenFollowAmbig=false;}:statement)? { ## = #( #[NLabel], ## ); } | "case"^ constExpr COLON! statement | "default"^ COLON! statement // Selection statements: | "if"^ LPAREN! expr RPAREN! statement ( //standard if-else ambiguity options { warnWhenFollowAmbig = false; } : "else" statement )? | "switch"^ LPAREN! expr RPAREN! statement ; expr : assignExpr (options { /* MBZ: COMMA is ambiguous between comma expressions and argument lists. argExprList should get priority, and it does by being deeper in the expr rule tree and using (COMMA assignExpr)* */ warnWhenFollowAmbig = false; } : c:COMMA^ { #c.setType(NCommaExpr); } assignExpr )* ; assignExpr : conditionalExpr ( a:assignOperator! assignExpr { ## = #( #a, ## );} )? ; assignOperator : ASSIGN | DIV_ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN | STAR_ASSIGN | MOD_ASSIGN | RSHIFT_ASSIGN | LSHIFT_ASSIGN | BAND_ASSIGN | BOR_ASSIGN | BXOR_ASSIGN ; conditionalExpr : logicalOrExpr ( QUESTION^ expr COLON! conditionalExpr )? ; constExpr : conditionalExpr ; logicalOrExpr : logicalAndExpr ( LOR^ logicalAndExpr )* ; logicalAndExpr : inclusiveOrExpr ( LAND^ inclusiveOrExpr )* ; inclusiveOrExpr : exclusiveOrExpr ( BOR^ exclusiveOrExpr )* ; exclusiveOrExpr : bitAndExpr ( BXOR^ bitAndExpr )* ; bitAndExpr : equalityExpr ( BAND^ equalityExpr )* ; equalityExpr : relationalExpr ( ( EQUAL^ | NOT_EQUAL^ ) relationalExpr )* ; relationalExpr : shiftExpr ( ( LT^ | LTE^ | GT^ | GTE^ ) shiftExpr )* ; shiftExpr : additiveExpr ( ( LSHIFT^ | RSHIFT^ ) additiveExpr )* ; additiveExpr : multExpr ( ( PLUS^ | MINUS^ ) multExpr )* ; multExpr : castExpr ( ( STAR^ | DIV^ | MOD^ ) castExpr )* ; castExpr : ( LPAREN typeName RPAREN )=> LPAREN! typeName RPAREN! ( castExpr ) { ## = #( #[NCast, "("], ## ); } | unaryExpr ; typeName : specifierQualifierList (nonemptyAbstractDeclarator)? ; nonemptyAbstractDeclarator : ( pointerGroup ( (LPAREN ( nonemptyAbstractDeclarator | parameterTypeList )? RPAREN) | (LBRACKET (expr)? RBRACKET) )* | ( (LPAREN ( nonemptyAbstractDeclarator | parameterTypeList )? RPAREN) | (LBRACKET (expr)? RBRACKET) )+ ) { ## = #( #[NNonemptyAbstractDeclarator], ## ); } ; /* JTC: LR rules: abstractDeclarator : nonemptyAbstractDeclarator | // null ; nonemptyAbstractDeclarator : LPAREN nonemptyAbstractDeclarator RPAREN | abstractDeclarator LPAREN RPAREN | abstractDeclarator (LBRACKET (expr)? RBRACKET) | STAR abstractDeclarator ; */ unaryExpr : postfixExpr | INC^ unaryExpr | DEC^ unaryExpr | u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); } | "sizeof"^ ( ( LPAREN typeName )=> LPAREN typeName RPAREN | unaryExpr ) ; unaryOperator : BAND | STAR | PLUS | MINUS | BNOT | LNOT ; postfixExpr : primaryExpr ( postfixSuffix {## = #( #[NPostfixExpr], ## );} )? ; postfixSuffix : ( PTR ID | DOT ID | functionCall | LBRACKET expr RBRACKET | INC | DEC )+ ; functionCall : LPAREN^ (a:argExprList)? RPAREN { ##.setType( NFunctionCallArgs ); } ; primaryExpr : ID | charConst | intConst | floatConst | stringConst // JTC: // ID should catch the enumerator // leaving it in gives ambiguous err // | enumerator | LPAREN! expr RPAREN! { ## = #( #[NExpressionGroup, "("], ## ); } ; argExprList : assignExpr ( COMMA! assignExpr )* ; protected charConst : CharLiteral ; protected stringConst : (StringLiteral)+ { ## = #(#[NStringSeq], ##); } ; protected intConst : IntOctalConst | LongOctalConst | UnsignedOctalConst | IntIntConst | LongIntConst | UnsignedIntConst | IntHexConst | LongHexConst | UnsignedHexConst ; protected floatConst : FloatDoubleConst | DoubleDoubleConst | LongDoubleConst ; dummy : NTypedefName | NInitDecl | NDeclarator | NStructDeclarator | NDeclaration | NCast | NPointerGroup | NExpressionGroup | NFunctionCallArgs | NNonemptyAbstractDeclarator | NInitializer | NStatementExpr | NEmptyExpression | NParameterTypeList | NFunctionDef | NCompoundStatement | NParameterDeclaration | NCommaExpr | NUnaryExpr | NLabel | NPostfixExpr | NRangeExpr | NStringSeq | NInitializerElementLabel | NLcurlyInitializer | NAsmAttribute | NGnuAsmExpr | NTypeMissing ; { import CToken; import java.io.*; import LineObject; import antlr.*; } class StdCLexer extends Lexer; options { k = 3; exportVocab = STDC; testLiterals = false; } { LineObject lineObject = new LineObject(); String originalSource = ""; PreprocessorInfoChannel preprocessorInfoChannel = new PreprocessorInfoChannel(); int tokenNumber = 0; boolean countingTokens = true; int deferredLineCount = 0; public void setCountingTokens(boolean ct) { countingTokens = ct; if ( countingTokens ) { tokenNumber = 0; } else { tokenNumber = 1; } } public void setOriginalSource(String src) { originalSource = src; lineObject.setSource(src); } public void setSource(String src) { lineObject.setSource(src); } public PreprocessorInfoChannel getPreprocessorInfoChannel() { return preprocessorInfoChannel; } public void setPreprocessingDirective(String pre) { preprocessorInfoChannel.addLineForTokenNumber( pre, new Integer(tokenNumber) ); } protected Token makeToken(int t) { if ( t != Token.SKIP && countingTokens) { tokenNumber++; } CToken tok = (CToken) super.makeToken(t); tok.setLine(lineObject.line); tok.setSource(lineObject.source); tok.setTokenNumber(tokenNumber); lineObject.line += deferredLineCount; deferredLineCount = 0; return tok; } public void deferredNewline() { deferredLineCount++; } public void newline() { lineObject.newline(); } } protected Vocabulary : '\3'..'\377' ; /* Operators: */ ASSIGN : '=' ; COLON : ':' ; COMMA : ',' ; QUESTION : '?' ; SEMI : ';' ; PTR : "->" ; // DOT & VARARGS are commented out since they are generated as part of // the Number rule below due to some bizarre lexical ambiguity shme. // DOT : '.' ; protected DOT:; // VARARGS : "..." ; protected VARARGS:; LPAREN : '(' ; RPAREN : ')' ; LBRACKET : '[' ; RBRACKET : ']' ; LCURLY : '{' ; RCURLY : '}' ; EQUAL : "==" ; NOT_EQUAL : "!=" ; LTE : "<=" ; LT : "<" ; GTE : ">=" ; GT : ">" ; DIV : '/' ; DIV_ASSIGN : "/=" ; PLUS : '+' ; PLUS_ASSIGN : "+=" ; INC : "++" ; MINUS : '-' ; MINUS_ASSIGN : "-=" ; DEC : "--" ; STAR : '*' ; STAR_ASSIGN : "*=" ; MOD : '%' ; MOD_ASSIGN : "%=" ; RSHIFT : ">>" ; RSHIFT_ASSIGN : ">>=" ; LSHIFT : "<<" ; LSHIFT_ASSIGN : "<<=" ; LAND : "&&" ; LNOT : '!' ; LOR : "||" ; BAND : '&' ; BAND_ASSIGN : "&=" ; BNOT : '~' ; BOR : '|' ; BOR_ASSIGN : "|=" ; BXOR : '^' ; BXOR_ASSIGN : "^=" ; Whitespace : ( ( '\003'..'\010' | '\t' | '\013' | '\f' | '\016'.. '\037' | '\177'..'\377' | ' ' ) | "\r\n" { newline(); } | ( '\n' | '\r' ) { newline(); } ) { _ttype = Token.SKIP; } ; Comment : "/*" ( { LA(2) != '/' }? '*' | "\r\n" { deferredNewline(); } | ( '\r' | '\n' ) { deferredNewline(); } | ~( '*'| '\r' | '\n' ) )* "*/" { _ttype = Token.SKIP; } ; CPPComment : "//" ( ~('\n') )* { _ttype = Token.SKIP; } ; PREPROC_DIRECTIVE options { paraphrase = "a line directive"; } : '#' ( ( "line" || (( ' ' | '\t' | '\014')+ '0'..'9')) => LineDirective | (~'\n')* { setPreprocessingDirective(getText()); } ) { _ttype = Token.SKIP; } ; protected Space: ( ' ' | '\t' | '\014') ; protected LineDirective { boolean oldCountingTokens = countingTokens; countingTokens = false; } : { lineObject = new LineObject(); deferredLineCount = 0; } ("line")? //this would be for if the directive started "#line", but not there for GNU directives (Space)+ n:Number { lineObject.setLine(Integer.parseInt(n.getText())); } (Space)+ ( fn:StringLiteral { try { lineObject.setSource(fn.getText().substring(1,fn.getText().length()-1)); } catch (StringIndexOutOfBoundsException e) { /*not possible*/ } } | fi:ID { lineObject.setSource(fi.getText()); } )? (Space)* ("1" { lineObject.setEnteringFile(true); } )? (Space)* ("2" { lineObject.setReturningToFile(true); } )? (Space)* ("3" { lineObject.setSystemHeader(true); } )? (Space)* ("4" { lineObject.setTreatAsC(true); } )? (~('\r' | '\n'))* ("\r\n" | "\r" | "\n") { preprocessorInfoChannel.addLineForTokenNumber(new LineObject(lineObject), new Integer(tokenNumber)); countingTokens = oldCountingTokens; } ; /* Literals: */ /* * Note that we do NOT handle tri-graphs nor multi-byte sequences. */ /* * Note that we can't have empty character constants (even though we * can have empty strings :-). */ CharLiteral : '\'' ( Escape | ~( '\'' ) ) '\'' ; /* * Can't have raw imbedded newlines in string constants. Strict reading of * the standard gives odd dichotomy between newlines & carriage returns. * Go figure. */ StringLiteral : '"' ( Escape | ( '\r' { deferredNewline(); } | '\n' { deferredNewline(); _ttype = BadStringLiteral; } | '\\' '\n' { deferredNewline(); } ) | ~( '"' | '\r' | '\n' | '\\' ) )* '"' ; protected BadStringLiteral : // Imaginary token. ; /* * Handle the various escape sequences. * * Note carefully that these numeric escape *sequences* are *not* of the * same form as the C language numeric *constants*. * * There is no such thing as a binary numeric escape sequence. * * Octal escape sequences are either 1, 2, or 3 octal digits exactly. * * There is no such thing as a decimal escape sequence. * * Hexadecimal escape sequences are begun with a leading \x and continue * until a non-hexadecimal character is found. * * No real handling of tri-graph sequences, yet. */ protected Escape : '\\' ( options{warnWhenFollowAmbig=false;}: 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' | '"' | '\'' | '\\' | '?' | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit ( options{warnWhenFollowAmbig=false;}: Digit )? )? | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )? | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+ ) ; /* Numeric Constants: */ protected Digit : '0'..'9' ; protected LongSuffix : 'l' | 'L' ; protected UnsignedSuffix : 'u' | 'U' ; protected FloatSuffix : 'f' | 'F' ; protected Exponent : ( 'e' | 'E' ) ( '+' | '-' )? ( Digit )+ ; protected DoubleDoubleConst:; protected FloatDoubleConst:; protected LongDoubleConst:; protected IntOctalConst:; protected LongOctalConst:; protected UnsignedOctalConst:; protected IntIntConst:; protected LongIntConst:; protected UnsignedIntConst:; protected IntHexConst:; protected LongHexConst:; protected UnsignedHexConst:; Number : ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+ ( '.' ( Digit )* ( Exponent )? | Exponent ) { _ttype = DoubleDoubleConst; } ( FloatSuffix { _ttype = FloatDoubleConst; } | LongSuffix { _ttype = LongDoubleConst; } )? | ( "..." )=> "..." { _ttype = VARARGS; } | '.' { _ttype = DOT; } ( ( Digit )+ ( Exponent )? { _ttype = DoubleDoubleConst; } ( FloatSuffix { _ttype = FloatDoubleConst; } | LongSuffix { _ttype = LongDoubleConst; } )? )? | '0' ( '0'..'7' )* { _ttype = IntOctalConst; } ( LongSuffix { _ttype = LongOctalConst; } | UnsignedSuffix { _ttype = UnsignedOctalConst; } )? | '1'..'9' ( Digit )* { _ttype = IntIntConst; } ( LongSuffix { _ttype = LongIntConst; } | UnsignedSuffix { _ttype = UnsignedIntConst; } )? | '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+ { _ttype = IntHexConst; } ( LongSuffix { _ttype = LongHexConst; } | UnsignedSuffix { _ttype = UnsignedHexConst; } )? ; ID options { testLiterals = true; } : ( 'a'..'z' | 'A'..'Z' | '_' ) ( 'a'..'z' | 'A'..'Z' | '_' | '0'..'9' )* ; ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/GnuCTreeParser.gantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/GnuCTree0000664000175000017500000004552010647361554033252 0ustar ebourgebourg/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Copyright (c) Non, Inc. 1998 -- All Rights Reserved PROJECT: C Compiler MODULE: GnuCTreeParser FILE: GnuCTreeParser.g AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 DESCRIPTION: This tree grammar is for a Gnu C AST. No actions in it, subclass to do something useful. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ { import java.io.*; import antlr.CommonAST; import antlr.DumpASTVisitor; } class GnuCTreeParser extends TreeParser; options { importVocab = GNUC; buildAST = false; ASTLabelType = "TNode"; // Copied following options from java grammar. codeGenMakeSwitchThreshold = 2; codeGenBitsetTestThreshold = 3; } { int traceDepth = 0; public void reportError(RecognitionException ex) { if ( ex != null) { System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex ); ex.printStackTrace(System.err); } } public void reportError(NoViableAltException ex) { System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString()); TNode.printTree( ex.node ); ex.printStackTrace(System.err); } public void reportError(MismatchedTokenException ex) { if ( ex != null) { TNode.printTree( ex.node ); System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex ); ex.printStackTrace(System.err); } } public void reportError(String s) { System.err.println("ANTLR Error from String: " + s); } public void reportWarning(String s) { System.err.println("ANTLR Warning from String: " + s); } protected void match(AST t, int ttype) throws MismatchedTokenException { //System.out.println("match("+ttype+"); cursor is "+t); super.match(t, ttype); } public void match(AST t, BitSet b) throws MismatchedTokenException { //System.out.println("match("+b+"); cursor is "+t); super.match(t, b); } protected void matchNot(AST t, int ttype) throws MismatchedTokenException { //System.out.println("matchNot("+ttype+"); cursor is "+t); super.matchNot(t, ttype); } public void traceIn(String rname, AST t) { traceDepth += 1; for (int x=0; x typeName | expr ) RPAREN ) | "__complex" ; typedefName : #(NTypedefName ID) ; structSpecifier : #( "struct" structOrUnionBody ) ; unionSpecifier : #( "union" structOrUnionBody ) ; structOrUnionBody : ( (ID LCURLY) => ID LCURLY ( structDeclarationList )? RCURLY | LCURLY ( structDeclarationList )? RCURLY | ID ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ structDeclarationList : ( structDeclaration )+ ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ structDeclaration : specifierQualifierList structDeclaratorList ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ specifierQualifierList : ( typeSpecifier | typeQualifier )+ ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ structDeclaratorList : ( structDeclarator )+ ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ structDeclarator : #( NStructDeclarator ( declarator )? ( COLON expr )? ( attributeDecl )* ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ enumSpecifier : #( "enum" ( ID )? ( LCURLY enumList RCURLY )? ) ; enumList : ( enumerator )+ ; enumerator : ID ( ASSIGN expr )? ; attributeDecl: #( "__attribute" (.)* ) | #( NAsmAttribute LPAREN expr RPAREN ) ; initDeclList : ( initDecl )+ ; initDecl { String declName = ""; } : #( NInitDecl declarator ( attributeDecl )* ( ASSIGN initializer | COLON expr )? ) ; pointerGroup : #( NPointerGroup ( STAR ( typeQualifier )* )+ ) ; idList : ID ( COMMA ID )* ; initializer : #( NInitializer (initializerElementLabel)? expr ) | lcurlyInitializer ; initializerElementLabel : #( NInitializerElementLabel ( ( LBRACKET expr RBRACKET (ASSIGN)? ) | ID COLON | DOT ID ASSIGN ) ) ; lcurlyInitializer : #( NLcurlyInitializer initializerList RCURLY ) ; initializerList : ( initializer )* ; declarator : #( NDeclarator ( pointerGroup )? ( id:ID | LPAREN declarator RPAREN ) ( #( NParameterTypeList ( parameterTypeList | (idList)? ) RPAREN ) | LBRACKET ( expr )? RBRACKET )* ) ; parameterTypeList : ( parameterDeclaration ( COMMA | SEMI )? )+ ( VARARGS )? ; parameterDeclaration : #( NParameterDeclaration declSpecifiers (declarator | nonemptyAbstractDeclarator)? ) ; functionDef : #( NFunctionDef ( functionDeclSpecifiers)? declarator (declaration | VARARGS)* compoundStatement ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ functionDeclSpecifiers : ( functionStorageClassSpecifier | typeQualifier | typeSpecifier )+ ; declarationList : ( //ANTLR doesn't know that declarationList properly eats all the declarations //so it warns about the ambiguity options { warnWhenFollowAmbig = false; } : localLabelDecl | declaration )+ ; localLabelDecl : #("__label__" (ID)+ ) ; compoundStatement : #( NCompoundStatement ( declarationList | functionDef )* ( statementList )? RCURLY ) ; statementList : ( statement )+ ; statement : statementBody ; statementBody : SEMI // Empty statements | compoundStatement // Group of statements | #(NStatementExpr expr) // Expressions // Iteration statements: | #( "while" expr statement ) | #( "do" statement expr ) | #( "for" expr expr expr statement ) // Jump statements: | #( "goto" expr ) | "continue" | "break" | #( "return" ( expr )? ) // Labeled statements: | #( NLabel ID (statement)? ) | #( "case" expr (statement)? ) | #( "default" (statement)? ) // Selection statements: | #( "if" expr statement ( "else" statement )? ) | #( "switch" expr statement ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ expr : assignExpr | conditionalExpr | logicalOrExpr | logicalAndExpr | inclusiveOrExpr | exclusiveOrExpr | bitAndExpr | equalityExpr | relationalExpr | shiftExpr | additiveExpr | multExpr | castExpr | unaryExpr | postfixExpr | primaryExpr | commaExpr | emptyExpr | compoundStatementExpr | initializer | rangeExpr | gnuAsmExpr ; commaExpr : #(NCommaExpr expr expr) ; emptyExpr : NEmptyExpression ; compoundStatementExpr : #(LPAREN compoundStatement RPAREN) ; rangeExpr : #(NRangeExpr expr VARARGS expr) ; gnuAsmExpr : #(NGnuAsmExpr ("volatile")? LPAREN stringConst ( options { warnWhenFollowAmbig = false; }: COLON (strOptExprPair ( COMMA strOptExprPair)* )? ( options { warnWhenFollowAmbig = false; }: COLON (strOptExprPair ( COMMA strOptExprPair)* )? )? )? ( COLON stringConst ( COMMA stringConst)* )? RPAREN ) ; strOptExprPair : stringConst ( LPAREN expr RPAREN )? ; assignExpr : #( ASSIGN expr expr) | #( DIV_ASSIGN expr expr) | #( PLUS_ASSIGN expr expr) | #( MINUS_ASSIGN expr expr) | #( STAR_ASSIGN expr expr) | #( MOD_ASSIGN expr expr) | #( RSHIFT_ASSIGN expr expr) | #( LSHIFT_ASSIGN expr expr) | #( BAND_ASSIGN expr expr) | #( BOR_ASSIGN expr expr) | #( BXOR_ASSIGN expr expr) ; conditionalExpr : #( QUESTION expr (expr)? COLON expr ) ; logicalOrExpr : #( LOR expr expr) ; logicalAndExpr : #( LAND expr expr ) ; inclusiveOrExpr : #( BOR expr expr ) ; exclusiveOrExpr : #( BXOR expr expr ) ; bitAndExpr : #( BAND expr expr ) ; equalityExpr : #( EQUAL expr expr) | #( NOT_EQUAL expr expr) ; relationalExpr : #( LT expr expr) | #( LTE expr expr) | #( GT expr expr) | #( GTE expr expr) ; shiftExpr : #( LSHIFT expr expr) | #( RSHIFT expr expr) ; additiveExpr : #( PLUS expr expr) | #( MINUS expr expr) ; multExpr : #( STAR expr expr) | #( DIV expr expr) | #( MOD expr expr) ; castExpr : #( NCast typeName RPAREN expr) ; typeName : specifierQualifierList (nonemptyAbstractDeclarator)? ; nonemptyAbstractDeclarator : #( NNonemptyAbstractDeclarator ( pointerGroup ( (LPAREN ( nonemptyAbstractDeclarator | parameterTypeList )? RPAREN) | (LBRACKET (expr)? RBRACKET) )* | ( (LPAREN ( nonemptyAbstractDeclarator | parameterTypeList )? RPAREN) | (LBRACKET (expr)? RBRACKET) )+ ) ) ; unaryExpr : #( INC expr ) | #( DEC expr ) | #( NUnaryExpr unaryOperator expr) | #( "sizeof" ( ( LPAREN typeName )=> LPAREN typeName RPAREN | expr ) ) | #( "__alignof" ( ( LPAREN typeName )=> LPAREN typeName RPAREN | expr ) ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ unaryOperator : BAND | STAR | PLUS | MINUS | BNOT | LNOT | LAND | "__real" | "__imag" ; postfixExpr : #( NPostfixExpr primaryExpr ( PTR ID | DOT ID | #( NFunctionCallArgs (argExprList)? RPAREN ) | LBRACKET expr RBRACKET | INC | DEC )+ ) ; primaryExpr : ID | Number | charConst | stringConst // JTC: // ID should catch the enumerator // leaving it in gives ambiguous err // | enumerator | #( NExpressionGroup expr ) ; argExprList : ( expr )+ ; protected charConst : CharLiteral ; protected stringConst : #(NStringSeq (StringLiteral)+) ; protected intConst : IntOctalConst | LongOctalConst | UnsignedOctalConst | IntIntConst | LongIntConst | UnsignedIntConst | IntHexConst | LongHexConst | UnsignedHexConst ; protected floatConst : FloatDoubleConst | DoubleDoubleConst | LongDoubleConst ; ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/GnuCEmitter.gantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/GnuCEmit0000664000175000017500000010312010647361554033240 0ustar ebourgebourg/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Copyright (c) Non, Inc. 1998 -- All Rights Reserved PROJECT: C Compiler MODULE: GnuCEmitter FILE: GnuCEmitter.g AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 DESCRIPTION: This tree grammar is for a Gnu C AST. It turns the tree back into source code. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ { import java.io.*; import java.util.*; import antlr.CommonAST; import antlr.DumpASTVisitor; } class GnuCEmitter extends GnuCTreeParser; options { importVocab = GNUC; buildAST = false; ASTLabelType = "TNode"; // Copied following options from java grammar. codeGenMakeSwitchThreshold = 2; codeGenBitsetTestThreshold = 3; } { int tabs = 0; PrintStream currentOutput = System.out; int lineNum = 1; String currentSource = ""; LineObject trueSourceFile; final int lineDirectiveThreshold = Integer.MAX_VALUE; PreprocessorInfoChannel preprocessorInfoChannel = null; Stack sourceFiles = new Stack(); GnuCEmitter( PreprocessorInfoChannel preprocChannel ) { preprocessorInfoChannel = preprocChannel; } void initializePrinting() { Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber( new Integer(1) ); printPreprocs(preprocs); /* if ( currentSource.equals("") ) { trueSourceFile = new LineObject(currentSource); currentOutput.println("# 1 \"" + currentSource + "\"\n"); sourceFiles.push(trueSourceFile); } */ } void finalizePrinting() { // flush any leftover preprocessing instructions to the stream printPreprocs( preprocessorInfoChannel.extractLinesPrecedingTokenNumber( new Integer( preprocessorInfoChannel.getMaxTokenNumber() + 1 ) )); //print a newline so file ends at a new line currentOutput.println(); } void printPreprocs( Vector preprocs ) { // if there was a preprocessingDirective previous to this token then // print a newline and the directive, line numbers handled later if ( preprocs.size() > 0 ) { if ( trueSourceFile != null ) { currentOutput.println(); //make sure we're starting a new line unless this is the first line directive } lineNum++; Enumeration e = preprocs.elements(); while (e.hasMoreElements()) { Object o = e.nextElement(); if ( o.getClass().getName().equals("LineObject") ) { LineObject l = (LineObject) o; // we always return to the trueSourceFile, we never enter it from another file // force it to be returning if in fact we aren't currently in trueSourceFile if (( trueSourceFile != null ) //trueSource exists && ( !currentSource.equals(trueSourceFile.getSource()) ) //currently not in trueSource && ( trueSourceFile.getSource().equals(l.getSource()) ) ) { //returning to trueSource l.setEnteringFile( false ); l.setReturningToFile( true ); } // print the line directive currentOutput.println(l); lineNum = l.getLine(); currentSource = l.getSource(); // the very first line directive always represents the true sourcefile if ( trueSourceFile == null ) { trueSourceFile = new LineObject(currentSource); sourceFiles.push(trueSourceFile); } // keep our own stack of files entered if ( l.getEnteringFile() ) { sourceFiles.push(l); } // if returning to a file, pop the exited files off the stack if ( l.getReturningToFile() ) { LineObject top = (LineObject) sourceFiles.peek(); while (( top != trueSourceFile ) && (! l.getSource().equals(top.getSource()) )) { sourceFiles.pop(); top = (LineObject) sourceFiles.peek(); } } } else { // it was a #pragma or such currentOutput.println(o); lineNum++; } } } } void print( TNode t ) { int tLineNum = t.getLocalLineNum(); if ( tLineNum == 0 ) tLineNum = lineNum; Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber")); printPreprocs(preprocs); if ( (lineNum != tLineNum) ) { // we know we'll be newlines or a line directive or it probably // is just the case that this token is on the next line // either way start a new line and indent it currentOutput.println(); lineNum++; printTabs(); } if ( lineNum == tLineNum ){ // do nothing special, we're at the right place } else { int diff = tLineNum - lineNum; if ( lineNum < tLineNum ) { // print out the blank lines to bring us up to right line number for ( ; lineNum < tLineNum ; lineNum++ ) { currentOutput.println(); } printTabs(); } else { // just reset lineNum lineNum = tLineNum; } } currentOutput.print( t.getText() + " " ); } /* This was my attempt at being smart about line numbers It didn't work quite right but I don't know why, I didn't have enough test cases. Worked ok compiling rcs and ghostscript */ void printAddingLineDirectives( TNode t ) { int tLineNum = t.getLocalLineNum(); String tSource = (String) t.getAttribute("source"); if ( tSource == null ) tSource = currentSource; if ( tLineNum == 0 ) tLineNum = lineNum; Vector preprocs = preprocessorInfoChannel.extractLinesPrecedingTokenNumber((Integer)t.getAttribute("tokenNumber")); printPreprocs(preprocs); if ( (lineNum != tLineNum) || !currentSource.equals(tSource) ) { // we know we'll be newlines or a line directive or it probably // is just the case that this token is on the next line // either way start a new line and indent it currentOutput.println(); lineNum++; printTabs(); } if ( ( lineNum == tLineNum ) && ( currentSource.equals(tSource) ) ){ // do nothing special, we're at the right place } else if ( currentSource.equals(tSource) ) { int diff = tLineNum - lineNum; if (diff > 0 && diff < lineDirectiveThreshold) { // print out the blank lines to bring us up to right line number for ( ; lineNum < tLineNum ; lineNum++ ) { currentOutput.println(); } } else { // print line directive to get us to right line number // preserve flags 3 and 4 if present in current file if ( ! sourceFiles.empty() ) { LineObject l = (LineObject) sourceFiles.peek(); StringBuffer tFlags = new StringBuffer(""); if (l.getSystemHeader()) { tFlags.append(" 3"); } if (l.getTreatAsC()) { tFlags.append(" 4"); } currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags.toString()); lineNum = tLineNum; } } printTabs(); } else { // different source Enumeration sources = sourceFiles.elements(); // see if we're returning to a file we entered earlier boolean returningToEarlierFile = false; while (sources.hasMoreElements()) { LineObject l = (LineObject) sources.nextElement(); if (l.getSource().equals(tSource)) { returningToEarlierFile = true; break; } } if (returningToEarlierFile) { // pop off the files we're exiting, but never pop the trueSourceFile LineObject l = (LineObject) sourceFiles.peek(); while ( ( l != trueSourceFile ) &&(! l.getSource().equals(tSource) ) ) { sourceFiles.pop(); l = (LineObject) sourceFiles.peek(); } // put in the return flag, plus others as needed StringBuffer tFlags = new StringBuffer(" 2"); if (l.getSystemHeader()) { tFlags.append(" 3"); } if (l.getTreatAsC()) { tFlags.append(" 4"); } currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + tFlags); lineNum = tLineNum; currentSource = tSource; printTabs(); } else { // entering a file that wasn't in the original source // pretend we're entering it from top of stack currentOutput.println("# " + tLineNum + " \"" + tSource + "\"" + " 1"); lineNum = tLineNum; currentSource = tSource; printTabs(); } } currentOutput.print( t.getText() + " " ); } /** It is not ok to print newlines from the String passed in as it will screw up the line number handling **/ void print( String s ) { currentOutput.print( s + " " ); } void printTabs() { for ( int i = 0; i< tabs; i++ ) { currentOutput.print( "\t" ); } } void commaSep( TNode t ) { print( t ); if ( t.getNextSibling() != null ) { print( "," ); } } int traceDepth = 0; public void reportError(RecognitionException ex) { if ( ex != null) { System.err.println("ANTLR Tree Parsing RecognitionException Error: " + ex.getClass().getName() + " " + ex ); ex.printStackTrace(System.err); } } public void reportError(NoViableAltException ex) { System.err.println("ANTLR Tree Parsing NoViableAltException Error: " + ex.toString()); TNode.printTree( ex.node ); ex.printStackTrace(System.err); } public void reportError(MismatchedTokenException ex) { if ( ex != null) { TNode.printTree( ex.node ); System.err.println("ANTLR Tree Parsing MismatchedTokenException Error: " + ex ); ex.printStackTrace(System.err); } } public void reportError(String s) { System.err.println("ANTLR Error from String: " + s); } public void reportWarning(String s) { System.err.println("ANTLR Warning from String: " + s); } protected void match(AST t, int ttype) throws MismatchedTokenException { //System.out.println("match("+ttype+"); cursor is "+t); super.match(t, ttype); } public void match(AST t, BitSet b) throws MismatchedTokenException { //System.out.println("match("+b+"); cursor is "+t); super.match(t, b); } protected void matchNot(AST t, int ttype) throws MismatchedTokenException { //System.out.println("matchNot("+ttype+"); cursor is "+t); super.matchNot(t, ttype); } public void traceIn(String rname, AST t) { traceDepth += 1; for (int x=0; x typeName | expr ) rp:RPAREN { print( rp ); } ) | p:"__complex" { print( p ); } ; typedefName : #(NTypedefName i:ID { print( i ); } ) ; structSpecifier : #( a:"struct" { print( a ); } structOrUnionBody ) ; unionSpecifier : #( a:"union" { print( a ); } structOrUnionBody ) ; structOrUnionBody : ( (ID LCURLY) => i1:ID lc1:LCURLY { print( i1 ); print ( "{" ); tabs++; } ( structDeclarationList )? rc1:RCURLY { tabs--; print( rc1 ); } | lc2:LCURLY { print( lc2 ); tabs++; } ( structDeclarationList )? rc2:RCURLY { tabs--; print( rc2 ); } | i2:ID { print( i2 ); } ) ; structDeclarationList : ( structDeclaration { print( ";" ); } )+ ; structDeclaration : specifierQualifierList structDeclaratorList ; specifierQualifierList : ( typeSpecifier | typeQualifier )+ ; structDeclaratorList : structDeclarator ( { print(","); } structDeclarator )* ; structDeclarator : #( NStructDeclarator ( declarator )? ( c:COLON { print( c ); } expr )? ( attributeDecl )* ) ; enumSpecifier : #( a:"enum" { print( a ); } ( i:ID { print( i ); } )? ( lc:LCURLY { print( lc ); tabs++; } enumList rc:RCURLY { tabs--; print( rc ); } )? ) ; enumList : enumerator ( {print(",");} enumerator)* ; enumerator : i:ID { print( i ); } ( b:ASSIGN { print( b ); } expr )? ; attributeDecl: #( a:"__attribute" { print( a ); } (b:. { print( b ); } )* ) | #( n:NAsmAttribute { print( n ); } lp:LPAREN { print( lp ); } expr { print( ")" ); } rp:RPAREN { print( rp ); } ) ; initDeclList : initDecl ( { print( "," ); } initDecl )* ; initDecl { String declName = ""; } : #(NInitDecl declarator ( attributeDecl )* ( a:ASSIGN { print( a ); } initializer | b:COLON { print( b ); } expr )? ) ; pointerGroup : #( NPointerGroup ( a:STAR { print( a ); } ( typeQualifier )* )+ ) ; idList : i:ID { print( i ); } ( c:COMMA { print( c ); } id:ID { print( id ); } )* ; initializer : #( NInitializer (initializerElementLabel)? expr ) | lcurlyInitializer ; initializerElementLabel : #( NInitializerElementLabel ( ( l:LBRACKET { print( l ); } expr r:RBRACKET { print( r ); } (a1:ASSIGN { print( a1 ); } )? ) | i1:ID c:COLON { print( i1 ); print( c ); } | d:DOT i2:ID a2:ASSIGN { print( d ); print( i2 ); print( a2 ); } ) ) ; lcurlyInitializer : #(n:NLcurlyInitializer { print( n ); tabs++; } initializerList rc:RCURLY { tabs--; print( rc ); } ) ; initializerList : ( i:initializer { commaSep( i ); } )* ; declarator : #( NDeclarator ( pointerGroup )? ( id:ID { print( id ); } | lp:LPAREN { print( lp ); } declarator rp:RPAREN { print( rp ); } ) ( #( n:NParameterTypeList { print( n ); } ( parameterTypeList | (idList)? ) r:RPAREN { print( r ); } ) | lb:LBRACKET { print( lb );} ( expr )? rb:RBRACKET { print( rb ); } )* ) ; parameterTypeList : ( parameterDeclaration ( c:COMMA { print( c ); } | s:SEMI { print( s ); } )? )+ ( v:VARARGS { print( v ); } )? ; parameterDeclaration : #( NParameterDeclaration declSpecifiers (declarator | nonemptyAbstractDeclarator)? ) ; functionDef : #( NFunctionDef ( functionDeclSpecifiers)? declarator (declaration | v:VARARGS { print( v ); } )* compoundStatement ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ functionDeclSpecifiers : ( functionStorageClassSpecifier | typeQualifier | typeSpecifier )+ ; declarationList : ( //ANTLR doesn't know that declarationList properly eats all the declarations //so it warns about the ambiguity options { warnWhenFollowAmbig = false; } : localLabelDecl | declaration )+ ; localLabelDecl : #(a:"__label__" { print( a ); } ( i:ID { commaSep( i ); } )+ { print( ";" ); } ) ; compoundStatement : #( cs:NCompoundStatement { print( cs ); tabs++; } ( declarationList | functionDef )* ( statementList )? rc:RCURLY { tabs--; print( rc ); } ) ; statementList : ( statement )+ ; statement : statementBody ; statementBody : s:SEMI { print( s ); } | compoundStatement // Group of statements | #(NStatementExpr expr { print( ";" ); } ) // Expressions // Iteration statements: | #( w:"while" { print( w ); print( "(" ); } expr { print( ")" ); } statement ) | #( d:"do" { print( d ); } statement { print( " while ( " ); } expr { print( " );" ); } ) | #( f:"for" { print( f ); print( "(" ); } expr { print( ";" ); } expr { print( ";" ); } expr { print( ")" ); } statement ) // Jump statements: | #( g:"goto" { print( g );} expr { print( ";" ); } ) | c:"continue" { print( c ); print( ";" );} | b:"break" { print( b ); print( ";" );} | #( r:"return" { print( r ); } ( expr )? { print( ";" ); } ) // Labeled statements: | #( NLabel ni:ID { print( ni ); print( ":" ); } ( statement )? ) | #( ca:"case" { print( ca ); } expr { print( ":" ); } (statement)? ) | #( de:"default" { print( de ); print( ":" ); } (statement)? ) // Selection statements: | #( i:"if" { print( i ); print( "(" ); } expr { print( ")" ); } statement ( e:"else" { print( e ); } statement )? ) | #( sw:"switch" { print( sw ); print( "(" ); } expr { print( ")" ); } statement ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ expr : binaryExpr | conditionalExpr | castExpr | unaryExpr | postfixExpr | primaryExpr | emptyExpr | compoundStatementExpr | initializer | rangeExpr | gnuAsmExpr ; emptyExpr : NEmptyExpression ; compoundStatementExpr : #(l:LPAREN { print( l ); } compoundStatement r:RPAREN { print( r ); } ) ; rangeExpr : #(NRangeExpr expr v:VARARGS{ print( v ); } expr) ; gnuAsmExpr : #(n:NGnuAsmExpr { print( n ); } (v:"volatile" { print( v ); } )? lp:LPAREN { print( lp ); } stringConst ( options { warnWhenFollowAmbig = false; }: c1:COLON { print( c1 );} (strOptExprPair ( c2:COMMA { print( c2 ); } strOptExprPair)* )? ( options { warnWhenFollowAmbig = false; }: c3:COLON { print( c3 ); } (strOptExprPair ( c4:COMMA { print( c4 ); } strOptExprPair)* )? )? )? ( c5:COLON { print( c5 ); } stringConst ( c6:COMMA { print( c6 ); } stringConst )* )? rp:RPAREN { print( rp ); } ) ; strOptExprPair : stringConst ( l:LPAREN { print( l ); } expr r:RPAREN { print( r ); } )? ; binaryOperator : ASSIGN | DIV_ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN | STAR_ASSIGN | MOD_ASSIGN | RSHIFT_ASSIGN | LSHIFT_ASSIGN | BAND_ASSIGN | BOR_ASSIGN | BXOR_ASSIGN | LOR | LAND | BOR | BXOR | BAND | EQUAL | NOT_EQUAL | LT | LTE | GT | GTE | LSHIFT | RSHIFT | PLUS | MINUS | STAR | DIV | MOD | NCommaExpr ; binaryExpr : b:binaryOperator // no rules allowed as roots, so here I manually get // the first and second children of the binary operator // and then print them out in the right order { TNode e1, e2; e1 = (TNode) b.getFirstChild(); e2 = (TNode) e1.getNextSibling(); expr( e1 ); print( b ); expr( e2 ); } ; conditionalExpr : #( q:QUESTION expr { print( q ); } ( expr )? c:COLON { print( c ); } expr ) ; castExpr : #( c:NCast { print( c ); } typeName rp:RPAREN { print( rp ); } expr ) ; typeName : specifierQualifierList (nonemptyAbstractDeclarator)? ; nonemptyAbstractDeclarator : #( NNonemptyAbstractDeclarator ( pointerGroup ( (lp1:LPAREN { print( lp1 ); } ( nonemptyAbstractDeclarator | parameterTypeList )? rp1:RPAREN { print( rp1 ); } ) | ( lb1:LBRACKET { print( lb1 ); } (expr)? rb1:RBRACKET { print( rb1 ); } ) )* | ( (lp2:LPAREN { print( lp2 ); } ( nonemptyAbstractDeclarator | parameterTypeList )? rp2:RPAREN { print( rp2 ); } ) | ( lb2:LBRACKET { print( lb2 ); } (expr)? rb2:RBRACKET { print( rb2 ); } ) )+ ) ) ; unaryExpr : #( i:INC { print( i ); } expr ) | #( d:DEC { print( d ); } expr ) | #( NUnaryExpr u:unaryOperator { print( u ); } expr) | #( s:"sizeof" { print( s ); } ( ( LPAREN typeName )=> lps:LPAREN { print( lps ); } typeName rps:RPAREN { print( rps ); } | expr ) ) | #( a:"__alignof" { print( a ); } ( ( LPAREN typeName )=> lpa:LPAREN { print( lpa ); } typeName rpa:RPAREN { print( rpa ); } | expr ) ) ; /* exception catch [RecognitionException ex] { reportError(ex); System.out.println("PROBLEM TREE:\n" + _t.toStringList()); if (_t!=null) {_t = _t.getNextSibling();} } */ unaryOperator : BAND | STAR | PLUS | MINUS | BNOT | LNOT | LAND | "__real" | "__imag" ; postfixExpr : #( NPostfixExpr primaryExpr ( a:PTR b:ID { print( a ); print( b ); } | c:DOT d:ID { print( c ); print( d ); } | #( n:NFunctionCallArgs { print( n ); } (argExprList)? rp:RPAREN { print( rp ); } ) | lb:LBRACKET { print( lb ); } expr rb:RBRACKET { print( rb ); } | f:INC { print( f ); } | g:DEC { print( g ); } )+ ) ; primaryExpr : i:ID { print( i ); } | n:Number { print( n ); } | charConst | stringConst // JTC: // ID should catch the enumerator // leaving it in gives ambiguous err // | enumerator | #( eg:NExpressionGroup { print( eg ); } expr { print( ")" ); } ) ; argExprList : expr ( {print( "," );} expr )* ; protected charConst : c:CharLiteral { print( c ); } ; protected stringConst : #( NStringSeq ( s:StringLiteral { print( s ); } )+ ) ; protected intConst : IntOctalConst | LongOctalConst | UnsignedOctalConst | IntIntConst | LongIntConst | UnsignedIntConst | IntHexConst | LongHexConst | UnsignedHexConst ; protected floatConst : FloatDoubleConst | DoubleDoubleConst | LongDoubleConst ; ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/GnuCParser.gantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-inheritance-test/src/main/antlr/GnuCPars0000664000175000017500000006505210647361554033262 0ustar ebourgebourg/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Copyright (c) Non, Inc. 1998 -- All Rights Reserved PROJECT: C Compiler MODULE: GnuCParser FILE: GnuCParser.g AUTHOR: Monty Zukowski (jamz@cdsnet.net) April 28, 1998 DESCRIPTION: This is a grammar for the GNU C compiler. It is a grammar subclass of StdCParser, overriding only those rules which are different from Standard C. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ { import java.io.*; import antlr.CommonAST; import antlr.DumpASTVisitor; } class GnuCParser extends StdCParser; options { k = 2; exportVocab = GNUC; buildAST = true; ASTLabelType = "TNode"; // Copied following options from java grammar. codeGenMakeSwitchThreshold = 2; codeGenBitsetTestThreshold = 3; } { // Suppport C++-style single-line comments? public static boolean CPPComments = true; // access to symbol table public CSymbolTable symbolTable = new CSymbolTable(); // source for names to unnamed scopes protected int unnamedScopeCounter = 0; public boolean isTypedefName(String name) { boolean returnValue = false; TNode node = symbolTable.lookupNameInCurrentScope(name); for (; node != null; node = (TNode) node.getNextSibling() ) { if(node.getType() == LITERAL_typedef) { returnValue = true; break; } } return returnValue; } public String getAScopeName() { return "" + (unnamedScopeCounter++); } public void pushScope(String scopeName) { symbolTable.pushScope(scopeName); } public void popScope() { symbolTable.popScope(); } int traceDepth = 0; public void reportError(RecognitionException ex) { try { System.err.println("ANTLR Parsing Error: "+ex + " token name:" + tokenNames[LA(1)]); ex.printStackTrace(System.err); } catch (TokenStreamException e) { System.err.println("ANTLR Parsing Error: "+ex); ex.printStackTrace(System.err); } } public void reportError(String s) { System.err.println("ANTLR Parsing Error from String: " + s); } public void reportWarning(String s) { System.err.println("ANTLR Parsing Warning from String: " + s); } public void match(int t) throws MismatchedTokenException { boolean debugging = false; if ( debugging ) { for (int x=0; x0)?" [inputState.guessing "+ inputState.guessing + "]":"")); } } try { if ( LA(1)!=t ) { if ( debugging ){ for (int x=0; x "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()] + ") " + LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]"); } catch (TokenStreamException e) { } } public void traceOut(String rname) { for (int x=0; x declaration | ( functionPrefix )=> functionDef | typelessDeclaration | asm_expr | SEMI ; /* these two are here because GCC allows "cat = 13;" as a valid program! */ functionPrefix { String declName; } : ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers | //epsilon ) declName = d:declarator[true] ( declaration )* (VARARGS)? ( SEMI )* LCURLY ; typelessDeclaration { AST typeMissing = #[NTypeMissing]; } : initDeclList[typeMissing] SEMI { ## = #( #[NTypeMissing], ##); } ; initializer : ( ( ( (initializerElementLabel)=> initializerElementLabel )? ( assignExpr | lcurlyInitializer ) { ## = #( #[NInitializer], ## ); } ) | lcurlyInitializer ) ; // GCC allows more specific initializers initializerElementLabel : ( ( LBRACKET ((constExpr VARARGS)=> rangeExpr | constExpr) RBRACKET (ASSIGN)? ) | ID COLON | DOT ID ASSIGN ) { ## = #( #[NInitializerElementLabel], ##) ; } ; // GCC allows empty initializer lists lcurlyInitializer : LCURLY^ (initializerList ( COMMA! )? )? RCURLY { ##.setType( NLcurlyInitializer ); } ; initializerList : initializer ( options{warnWhenFollowAmbig=false;}:COMMA! initializer )* ; declarator[boolean isFunctionDefinition] returns [String declName] { declName = ""; } : ( pointerGroup )? ( id:ID { declName = id.getText(); } | LPAREN declName = declarator[false] RPAREN ) ( declaratorParamaterList[isFunctionDefinition, declName] | LBRACKET ( expr )? RBRACKET )* { ## = #( #[NDeclarator], ## ); } ; declaratorParamaterList[boolean isFunctionDefinition, String declName] : LPAREN^ { if (isFunctionDefinition) { pushScope(declName); } else { pushScope("!"+declName); } } ( (declSpecifiers)=> parameterTypeList | (idList)? ) { popScope(); } ( COMMA! )? RPAREN { ##.setType(NParameterTypeList); } ; parameterTypeList : parameterDeclaration ( options { warnWhenFollowAmbig = false; } : ( COMMA | SEMI ) parameterDeclaration )* ( ( COMMA | SEMI ) VARARGS )? ; declarationList : ( options { // this loop properly aborts when // it finds a non-typedefName ID MBZ warnWhenFollowAmbig = false; } : localLabelDeclaration | ( declarationPredictor )=> declaration )+ ; localLabelDeclaration : ( //GNU note: any __label__ declarations must come before regular declarations. "__label__"^ ID (options{warnWhenFollowAmbig=false;}: COMMA! ID)* ( COMMA! )? ( SEMI! )+ ) ; declaration { AST ds1 = null; } : ds:declSpecifiers { ds1 = astFactory.dupList(#ds); } ( initDeclList[ds1] )? ( SEMI )+ { ## = #( #[NDeclaration], ##); } ; functionStorageClassSpecifier : "extern" | "static" | "inline" ; typeSpecifier [int specCount] returns [int retSpecCount] { retSpecCount = specCount + 1; } : ( "void" | "char" | "short" | "int" | "long" | "float" | "double" | "signed" | "unsigned" | structOrUnionSpecifier ( options{warnWhenFollowAmbig=false;}: attributeDecl )* | enumSpecifier | { specCount==0 }? typedefName | "typeof"^ LPAREN ( ( typeName )=> typeName | expr ) RPAREN | "__complex" ) ; structOrUnionSpecifier { String scopeName; } : sou:structOrUnion! ( ( ID LCURLY )=> i:ID l:LCURLY { scopeName = #sou.getText() + " " + #i.getText(); #l.setText(scopeName); pushScope(scopeName); } ( structDeclarationList )? { popScope();} RCURLY | l1:LCURLY { scopeName = getAScopeName(); #l1.setText(scopeName); pushScope(scopeName); } ( structDeclarationList )? { popScope(); } RCURLY | ID ) { ## = #( #sou, ## ); } ; structDeclaration : specifierQualifierList structDeclaratorList ( COMMA! )? ( SEMI! )+ ; structDeclaratorList : structDeclarator ( options{warnWhenFollowAmbig=false;}: COMMA! structDeclarator )* ; structDeclarator : ( declarator[false] )? ( COLON constExpr )? ( attributeDecl )* { ## = #( #[NStructDeclarator], ##); } ; enumSpecifier : "enum"^ ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY | LCURLY enumList["anonymous"] RCURLY | ID ) ; enumList[String enumName] : enumerator[enumName] ( options{warnWhenFollowAmbig=false;}: COMMA! enumerator[enumName] )* ( COMMA! )? ; initDeclList[AST declarationSpecifiers] : initDecl[declarationSpecifiers] ( options{warnWhenFollowAmbig=false;}: COMMA! initDecl[declarationSpecifiers] )* ( COMMA! )? ; initDecl[AST declarationSpecifiers] { String declName = ""; } : declName = d:declarator[false] { AST ds1, d1; ds1 = astFactory.dupList(declarationSpecifiers); d1 = astFactory.dupList(#d); symbolTable.add(declName, #(null, ds1, d1) ); } ( attributeDecl )* ( ASSIGN initializer | COLON expr )? { ## = #( #[NInitDecl], ## ); } ; attributeDecl : "__attribute"^ LPAREN LPAREN attributeList RPAREN RPAREN | "asm"^ LPAREN stringConst RPAREN { ##.setType( NAsmAttribute ); } ; attributeList : attribute ( options{warnWhenFollowAmbig=false;}: COMMA attribute)* ( COMMA )? ; attribute : ( ~(LPAREN | RPAREN | COMMA) | LPAREN attributeList RPAREN )* ; compoundStatement[String scopeName] : LCURLY^ { pushScope(scopeName); } ( //this ambiguity is ok, declarationList and nestedFunctionDef end properly options { warnWhenFollowAmbig = false; } : ( "typedef" | "__label__" | declaration )=> declarationList | (nestedFunctionDef)=> nestedFunctionDef )* ( statementList )? { popScope(); } RCURLY { ##.setType( NCompoundStatement ); ##.setAttribute( "scopeName", scopeName ); } ; nestedFunctionDef { String declName; } : ( "auto" )? //only for nested functions ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers )? declName = d:declarator[false] { AST d2, ds2; d2 = astFactory.dupList(#d); ds2 = astFactory.dupList(#ds); symbolTable.add(declName, #(null, ds2, d2)); pushScope(declName); } ( declaration )* { popScope(); } compoundStatement[declName] { ## = #( #[NFunctionDef], ## );} ; statement : SEMI // Empty statements | compoundStatement[getAScopeName()] // Group of statements | expr SEMI! { ## = #( #[NStatementExpr], ## );} // Expressions // Iteration statements: | "while"^ LPAREN! expr RPAREN! statement | "do"^ statement "while"! LPAREN! expr RPAREN! SEMI! |! "for" LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN s:statement { if ( #e1 == null) { #e1 = #[ NEmptyExpression ]; } if ( #e2 == null) { #e2 = #[ NEmptyExpression ]; } if ( #e3 == null) { #e3 = #[ NEmptyExpression ]; } ## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s ); } // Jump statements: | "goto"^ expr SEMI! | "continue" SEMI! | "break" SEMI! | "return"^ ( expr )? SEMI! | ID COLON! (options {warnWhenFollowAmbig=false;}: statement)? { ## = #( #[NLabel], ## ); } // GNU allows range expressions in case statements | "case"^ ((constExpr VARARGS)=> rangeExpr | constExpr) COLON! ( options{warnWhenFollowAmbig=false;}:statement )? | "default"^ COLON! ( options{warnWhenFollowAmbig=false;}: statement )? // Selection statements: | "if"^ LPAREN! expr RPAREN! statement ( //standard if-else ambiguity options { warnWhenFollowAmbig = false; } : "else" statement )? | "switch"^ LPAREN! expr RPAREN! statement ; conditionalExpr : logicalOrExpr ( QUESTION^ (expr)? COLON conditionalExpr )? ; rangeExpr //used in initializers only : constExpr VARARGS constExpr { ## = #(#[NRangeExpr], ##); } ; castExpr : ( LPAREN typeName RPAREN )=> LPAREN^ typeName RPAREN ( castExpr | lcurlyInitializer ) { ##.setType(NCast); } | unaryExpr ; nonemptyAbstractDeclarator : ( pointerGroup ( (LPAREN ( nonemptyAbstractDeclarator | parameterTypeList )? ( COMMA! )? RPAREN) | (LBRACKET (expr)? RBRACKET) )* | ( (LPAREN ( nonemptyAbstractDeclarator | parameterTypeList )? ( COMMA! )? RPAREN) | (LBRACKET (expr)? RBRACKET) )+ ) { ## = #( #[NNonemptyAbstractDeclarator], ## ); } ; unaryExpr : postfixExpr | INC^ castExpr | DEC^ castExpr | u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); } | "sizeof"^ ( ( LPAREN typeName )=> LPAREN typeName RPAREN | unaryExpr ) | "__alignof"^ ( ( LPAREN typeName )=> LPAREN typeName RPAREN | unaryExpr ) | gnuAsmExpr ; unaryOperator : BAND | STAR | PLUS | MINUS | BNOT //also stands for complex conjugation | LNOT | LAND //for label dereference (&&label) | "__real" | "__imag" ; gnuAsmExpr : "asm"^ ("volatile")? LPAREN stringConst ( options { warnWhenFollowAmbig = false; }: COLON (strOptExprPair ( COMMA strOptExprPair)* )? ( options { warnWhenFollowAmbig = false; }: COLON (strOptExprPair ( COMMA strOptExprPair)* )? )? )? ( COLON stringConst ( COMMA stringConst)* )? RPAREN { ##.setType(NGnuAsmExpr); } ; //GCC requires the PARENs strOptExprPair : stringConst ( LPAREN expr RPAREN )? ; primaryExpr : ID | Number | charConst | stringConst // JTC: // ID should catch the enumerator // leaving it in gives ambiguous err // | enumerator | (LPAREN LCURLY) => LPAREN^ compoundStatement[getAScopeName()] RPAREN | LPAREN^ expr RPAREN { ##.setType(NExpressionGroup); } ; { import CToken; import java.io.*; import LineObject; import antlr.*; } class GnuCLexer extends StdCLexer; options { k = 3; importVocab = GNUC; testLiterals = false; } tokens { LITERAL___extension__ = "__extension__"; } { public void initialize(String src) { setOriginalSource(src); initialize(); } public void initialize() { literals.put(new ANTLRHashString("__alignof__", this), new Integer(LITERAL___alignof)); literals.put(new ANTLRHashString("__asm", this), new Integer(LITERAL_asm)); literals.put(new ANTLRHashString("__asm__", this), new Integer(LITERAL_asm)); literals.put(new ANTLRHashString("__attribute__", this), new Integer(LITERAL___attribute)); literals.put(new ANTLRHashString("__complex__", this), new Integer(LITERAL___complex)); literals.put(new ANTLRHashString("__const", this), new Integer(LITERAL_const)); literals.put(new ANTLRHashString("__const__", this), new Integer(LITERAL_const)); literals.put(new ANTLRHashString("__imag__", this), new Integer(LITERAL___imag)); literals.put(new ANTLRHashString("__inline", this), new Integer(LITERAL_inline)); literals.put(new ANTLRHashString("__inline__", this), new Integer(LITERAL_inline)); literals.put(new ANTLRHashString("__real__", this), new Integer(LITERAL___real)); literals.put(new ANTLRHashString("__signed", this), new Integer(LITERAL_signed)); literals.put(new ANTLRHashString("__signed__", this), new Integer(LITERAL_signed)); literals.put(new ANTLRHashString("__typeof", this), new Integer(LITERAL_typeof)); literals.put(new ANTLRHashString("__typeof__", this), new Integer(LITERAL_typeof)); literals.put(new ANTLRHashString("__volatile", this), new Integer(LITERAL_volatile)); literals.put(new ANTLRHashString("__volatile__", this), new Integer(LITERAL_volatile)); } LineObject lineObject = new LineObject(); String originalSource = ""; PreprocessorInfoChannel preprocessorInfoChannel = new PreprocessorInfoChannel(); int tokenNumber = 0; boolean countingTokens = true; int deferredLineCount = 0; public void setCountingTokens(boolean ct) { countingTokens = ct; if ( countingTokens ) { tokenNumber = 0; } else { tokenNumber = 1; } } public void setOriginalSource(String src) { originalSource = src; lineObject.setSource(src); } public void setSource(String src) { lineObject.setSource(src); } public PreprocessorInfoChannel getPreprocessorInfoChannel() { return preprocessorInfoChannel; } public void setPreprocessingDirective(String pre) { preprocessorInfoChannel.addLineForTokenNumber( pre, new Integer(tokenNumber) ); } protected Token makeToken(int t) { if ( t != Token.SKIP && countingTokens) { tokenNumber++; } CToken tok = (CToken) super.makeToken(t); tok.setLine(lineObject.line); tok.setSource(lineObject.source); tok.setTokenNumber(tokenNumber); lineObject.line += deferredLineCount; deferredLineCount = 0; return tok; } public void deferredNewline() { deferredLineCount++; } public void newline() { lineObject.newline(); } } Whitespace : ( ( ' ' | '\t' | '\014') | "\r\n" { newline(); } | ( '\n' | '\r' ) { newline(); } ) { _ttype = Token.SKIP; } ; protected Escape : '\\' ( options{warnWhenFollowAmbig=false;}: ~('0'..'7' | 'x') | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit )* | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )* | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+ ) ; protected IntSuffix : 'L' | 'l' | 'U' | 'u' | 'I' | 'i' | 'J' | 'j' ; protected NumberSuffix : IntSuffix | 'F' | 'f' ; Number : ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+ ( '.' ( Digit )* ( Exponent )? | Exponent ) ( NumberSuffix )* | ( "..." )=> "..." { _ttype = VARARGS; } | '.' { _ttype = DOT; } ( ( Digit )+ ( Exponent )? { _ttype = Number; } ( NumberSuffix )* )? | '0' ( '0'..'7' )* ( NumberSuffix )* | '1'..'9' ( Digit )* ( NumberSuffix )* | '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+ ( IntSuffix )* ; IDMEAT : i:ID { if ( i.getType() == LITERAL___extension__ ) { $setType(Token.SKIP); } else { $setType(i.getType()); } } ; protected ID options { testLiterals = true; } : ( 'a'..'z' | 'A'..'Z' | '_' | '$') ( 'a'..'z' | 'A'..'Z' | '_' | '$' | '0'..'9' )* ; WideCharLiteral : 'L' CharLiteral { $setType(CharLiteral); } ; WideStringLiteral : 'L' StringLiteral { $setType(StringLiteral); } ; StringLiteral : '"' ( ('\\' ~('\n'))=> Escape | ( '\r' { newline(); } | '\n' { newline(); } | '\\' '\n' { newline(); } ) | ~( '"' | '\r' | '\n' | '\\' ) )* '"' ; antlr-maven-plugin-2.2/src/test/resources/unit/no-antlr-dep/0000775000175000017500000000000012165015352023466 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/no-antlr-dep/no-antlr-dep-test-plugin-config.xml0000664000175000017500000000361610773161441032236 0ustar ebourgebourg 4.0.0 org.codehaus.mojo.antlr no-dep-test jar 1.0-SNAPSHOT 2006 Maven Antlr Plugin Test - No Antlr Dep http://mojo.codehaus.org org.codehaus.mojo antlr-maven-plugin ${basedir}/target/test/unit/java-grammar-test/target/generated-sources/antlr ${basedir}/src/test/resources/unit/java-grammar-test/src/main/antlr java15.g antlr-maven-plugin-2.2/src/test/resources/unit/no-antlr-dep/src/0000775000175000017500000000000012165015351024254 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/no-antlr-dep/src/main/0000775000175000017500000000000012165015351025200 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/no-antlr-dep/src/main/antlr/0000775000175000017500000000000012165015352026321 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/no-antlr-dep/src/main/antlr/java15.g0000664000175000017500000014313510726025651027573 0ustar ebourgebourg/** Java 1.5 Recognizer * * Run 'java Main [-showtree] directory-full-of-java-files' * * [The -showtree option pops up a Swing frame that shows * the AST constructed from the parser.] * * Run 'java Main ' * * Contributing authors: * John Mitchell johnm@non.net * Terence Parr parrt@magelang.com * John Lilley jlilley@empathy.com * Scott Stanchfield thetick@magelang.com * Markus Mohnen mohnen@informatik.rwth-aachen.de * Peter Williams pete.williams@sun.com * Allan Jacobs Allan.Jacobs@eng.sun.com * Steve Messick messick@redhills.com * John Pybus john@pybus.org * * Version 1.00 December 9, 1997 -- initial release * Version 1.01 December 10, 1997 * fixed bug in octal def (0..7 not 0..8) * Version 1.10 August 1998 (parrt) * added tree construction * fixed definition of WS,comments for mac,pc,unix newlines * added unary plus * Version 1.11 (Nov 20, 1998) * Added "shutup" option to turn off last ambig warning. * Fixed inner class def to allow named class defs as statements * synchronized requires compound not simple statement * add [] after builtInType DOT class in primaryExpression * "const" is reserved but not valid..removed from modifiers * Version 1.12 (Feb 2, 1999) * Changed LITERAL_xxx to xxx in tree grammar. * Updated java.g to use tokens {...} now for 2.6.0 (new feature). * * Version 1.13 (Apr 23, 1999) * Didn't have (stat)? for else clause in tree parser. * Didn't gen ASTs for interface extends. Updated tree parser too. * Updated to 2.6.0. * Version 1.14 (Jun 20, 1999) * Allowed final/abstract on local classes. * Removed local interfaces from methods * Put instanceof precedence where it belongs...in relationalExpr * It also had expr not type as arg; fixed it. * Missing ! on SEMI in classBlock * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). * fixed: didn't like Object[].class in parser or tree parser * Version 1.15 (Jun 26, 1999) * Screwed up rule with instanceof in it. :( Fixed. * Tree parser didn't like (expr).something; fixed. * Allowed multiple inheritance in tree grammar. oops. * Version 1.16 (August 22, 1999) * Extending an interface built a wacky tree: had extra EXTENDS. * Tree grammar didn't allow multiple superinterfaces. * Tree grammar didn't allow empty var initializer: {} * Version 1.17 (October 12, 1999) * ESC lexer rule allowed 399 max not 377 max. * java.tree.g didn't handle the expression of synchronized * statements. * Version 1.18 (August 12, 2001) * Terence updated to Java 2 Version 1.3 by * observing/combining work of Allan Jacobs and Steve * Messick. Handles 1.3 src. Summary: * o primary didn't include boolean.class kind of thing * o constructor calls parsed explicitly now: * see explicitConstructorInvocation * o add strictfp modifier * o missing objBlock after new expression in tree grammar * o merged local class definition alternatives, moved after declaration * o fixed problem with ClassName.super.field * o reordered some alternatives to make things more efficient * o long and double constants were not differentiated from int/float * o whitespace rule was inefficient: matched only one char * o add an examples directory with some nasty 1.3 cases * o made Main.java use buffered IO and a Reader for Unicode support * o supports UNICODE? * Using Unicode charVocabulay makes code file big, but only * in the bitsets at the end. I need to make ANTLR generate * unicode bitsets more efficiently. * Version 1.19 (April 25, 2002) * Terence added in nice fixes by John Pybus concerning floating * constants and problems with super() calls. John did a nice * reorg of the primary/postfix expression stuff to read better * and makes f.g.super() parse properly (it was METHOD_CALL not * a SUPER_CTOR_CALL). Also: * * o "finally" clause was a root...made it a child of "try" * o Added stuff for asserts too for Java 1.4, but *commented out* * as it is not backward compatible. * * Version 1.20 (October 27, 2002) * * Terence ended up reorging John Pybus' stuff to * remove some nondeterminisms and some syntactic predicates. * Note that the grammar is stricter now; e.g., this(...) must * be the first statement. * * Trinary ?: operator wasn't working as array name: * (isBig ? bigDigits : digits)[i]; * * Checked parser/tree parser on source for * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, * and the 110k-line jGuru server source. * * Version 1.21 (October 17, 2003) * Fixed lots of problems including: * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g * He found a problem/fix with floating point that start with 0 * Ray also fixed problem that (int.class) was not recognized. * Thorsten van Ellen noticed that \n are allowed incorrectly in strings. * TJP fixed CHAR_LITERAL analogously. * * Version 1.21.2 (March, 2003) * Changes by Matt Quail to support generics (as per JDK1.5/JSR14) * Notes: * o We only allow the "extends" keyword and not the "implements" * keyword, since thats what JSR14 seems to imply. * o Thanks to Monty Zukowski for his help on the antlr-interest * mail list. * o Thanks to Alan Eliasen for testing the grammar over his * Fink source base * * Version 1.22 (July, 2004) * Changes by Michael Studman to support Java 1.5 language extensions * Notes: * o Added support for annotations types * o Finished off Matt Quail's generics enhancements to support bound type arguments * o Added support for new for statement syntax * o Added support for static import syntax * o Added support for enum types * o Tested against JDK 1.5 source base and source base of jdigraph project * o Thanks to Matt Quail for doing the hard part by doing most of the generics work * * Version 1.22.1 (July 28, 2004) * Bug/omission fixes for Java 1.5 language support * o Fixed tree structure bug with classOrInterface - thanks to Pieter Vangorpto for * spotting this * o Fixed bug where incorrect handling of SR and BSR tokens would cause type * parameters to be recognised as type arguments. * o Enabled type parameters on constructors, annotations on enum constants * and package definitions * o Fixed problems when parsing if ((char.class.equals(c))) {} - solution by Matt Quail at Cenqua * * Version 1.22.2 (July 28, 2004) * Slight refactoring of Java 1.5 language support * o Refactored for/"foreach" productions so that original literal "for" literal * is still used but the for sub-clauses vary by token type * o Fixed bug where type parameter was not included in generic constructor's branch of AST * * Version 1.22.3 (August 26, 2004) * Bug fixes as identified by Michael Stahl; clean up of tabs/spaces * and other refactorings * o Fixed typeParameters omission in identPrimary and newStatement * o Replaced GT reconcilliation code with simple semantic predicate * o Adapted enum/assert keyword checking support from Michael Stahl's java15 grammar * o Refactored typeDefinition production and field productions to reduce duplication * * Version 1.22.4 (October 21, 2004) * Small bux fixes * o Added typeArguments to explicitConstructorInvocation, e.g. new MyParameterised() * o Added typeArguments to postfixExpression productions for anonymous inner class super * constructor invocation, e.g. new Outer().super() * o Fixed bug in array declarations identified by Geoff Roy * * Version 1.22.5 (January 03, 2005) * Small change to tree structure * o Flattened classOrInterfaceType tree so IDENT no longer has children. TYPE_ARGUMENTS are now * always siblings of IDENT rather than children. Fully.qualified.names trees now * look a little less clean when TYPE_ARGUMENTS are present though. * * This grammar is in the PUBLIC DOMAIN */ 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; VARIABLE_PARAMETER_DEF; STATIC_IMPORT; ENUM_DEF; ENUM_CONSTANT_DEF; FOR_EACH_CLAUSE; ANNOTATION_DEF; ANNOTATIONS; ANNOTATION; ANNOTATION_MEMBER_VALUE_PAIR; ANNOTATION_FIELD_DEF; ANNOTATION_ARRAY_INIT; TYPE_ARGUMENTS; TYPE_ARGUMENT; TYPE_PARAMETERS; TYPE_PARAMETER; WILDCARD_TYPE; TYPE_UPPER_BOUNDS; TYPE_LOWER_BOUNDS; } { /** * Counts the number of LT seen in the typeArguments production. * It is used in semantic predicates to ensure we have seen * enough closing '>' characters; which actually may have been * either GT, SR or BSR tokens. */ private int ltCounter = 0; } // Compilation Unit: In Java, this is a single file. This is the start // rule for this parser compilationUnit : // A compilation unit starts with an optional package definition ( (annotations "package")=> 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! ; // Package statement: optional annotations followed by "package" then the package identifier. packageDefinition options {defaultErrorHandler = true;} // let ANTLR handle errors : annotations p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! ; // Import statement: import followed by a package or class name importDefinition options {defaultErrorHandler = true;} { boolean isStatic = false; } : i:"import"^ {#i.setType(IMPORT);} ( "static"! {#i.setType(STATIC_IMPORT);} )? identifierStar SEMI! ; // A type definition is either a class, interface, enum or annotation with possible additional semis. typeDefinition options {defaultErrorHandler = true;} : m:modifiers! typeDefinitionInternal[#m] | SEMI! ; // Protected type definitions production for reuse in other productions protected typeDefinitionInternal[AST mods] : classDefinition[#mods] // inner class | interfaceDefinition[#mods] // inner interface | enumDefinition[#mods] // inner enum | annotationDefinition[#mods] // inner annotation ; // 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 either: // - possible brackets afterwards // (which would make it an array type). // - generic type arguments after classTypeSpec[boolean addImagNode] : classOrInterfaceType[false] (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )* { if ( addImagNode ) { #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); } } ; // A non-built in type name, with possible type parameters classOrInterfaceType[boolean addImagNode] : IDENT (typeArguments)? (options{greedy=true;}: // match as many as possible DOT^ IDENT (typeArguments)? )* { if ( addImagNode ) { #classOrInterfaceType = #(#[TYPE,"TYPE"], #classOrInterfaceType); } } ; // A specialised form of typeSpec where built in types must be arrays typeArgumentSpec : classTypeSpec[true] | builtInTypeArraySpec[true] ; // A generic type argument is a class type, a possibly bounded wildcard type or a built-in type array typeArgument : ( typeArgumentSpec | wildcardType ) {#typeArgument = #(#[TYPE_ARGUMENT,"TYPE_ARGUMENT"], #typeArgument);} ; // Wildcard type indicating all types (with possible constraint) wildcardType : q:QUESTION^ {#q.setType(WILDCARD_TYPE);} (("extends" | "super")=> typeArgumentBounds)? ; // Type arguments to a class or interface type typeArguments {int currentLtLevel = 0;} : {currentLtLevel = ltCounter;} LT! {ltCounter++;} typeArgument (options{greedy=true;}: // match as many as possible {inputState.guessing !=0 || ltCounter == currentLtLevel + 1}? COMMA! typeArgument )* ( // turn warning off since Antlr generates the right code, // plus we have our semantic predicate below options{generateAmbigWarnings=false;}: typeArgumentsOrParametersEnd )? // make sure we have gobbled up enough '>' characters // if we are at the "top level" of nested typeArgument productions {(currentLtLevel != 0) || ltCounter == currentLtLevel}? {#typeArguments = #(#[TYPE_ARGUMENTS, "TYPE_ARGUMENTS"], #typeArguments);} ; // this gobbles up *some* amount of '>' characters, and counts how many // it gobbled. protected typeArgumentsOrParametersEnd : GT! {ltCounter-=1;} | SR! {ltCounter-=2;} | BSR! {ltCounter-=3;} ; // Restriction on wildcard types based on super class or derrived class typeArgumentBounds {boolean isUpperBounds = false;} : ( "extends"! {isUpperBounds=true;} | "super"! ) classOrInterfaceType[false] { if (isUpperBounds) { #typeArgumentBounds = #(#[TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS"], #typeArgumentBounds); } else { #typeArgumentBounds = #(#[TYPE_LOWER_BOUNDS,"TYPE_LOWER_BOUNDS"], #typeArgumentBounds); } } ; // A builtin type array specification is a builtin type with brackets afterwards builtInTypeArraySpec[boolean addImagNode] : builtInType (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )+ { if ( addImagNode ) { #builtInTypeArraySpec = #(#[TYPE,"TYPE"], #builtInTypeArraySpec); } } ; // A builtin type specification is a builtin type with possible brackets // afterwards (which would make it an array type). builtInTypeSpec[boolean addImagNode] : builtInType (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )* { if ( addImagNode ) { #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); } } ; // A type name. which is either a (possibly qualified and parameterized) // class name or a primitive (builtin) type type : classOrInterfaceType[false] | 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 IDENTS identifier : 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 desires modifiers : ( //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 = #([MODIFIERS, "MODIFIERS"], #modifiers);} ; // modifiers for Java classes, interfaces, class/instance vars and methods modifier : "private" | "public" | "protected" | "static" | "transient" | "final" | "abstract" | "native" | "threadsafe" | "synchronized" | "volatile" | "strictfp" ; annotation! : AT! i:identifier ( LPAREN! ( args:annotationArguments )? RPAREN! )? {#annotation = #(#[ANNOTATION,"ANNOTATION"], i, args);} ; annotations : (annotation)* {#annotations = #([ANNOTATIONS, "ANNOTATIONS"], #annotations);} ; annotationArguments : annotationMemberValueInitializer | anntotationMemberValuePairs ; anntotationMemberValuePairs : annotationMemberValuePair ( COMMA! annotationMemberValuePair )* ; annotationMemberValuePair! : i:IDENT ASSIGN! v:annotationMemberValueInitializer {#annotationMemberValuePair = #(#[ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR"], 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! : ( "extends" c:classOrInterfaceType[false] )? {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],c);} ; // Definition of a Java class classDefinition![AST modifiers] : "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 = #(#[CLASS_DEF,"CLASS_DEF"], modifiers,IDENT,tp,sc,ic,cb);} ; // Definition of a Java Interface interfaceDefinition![AST modifiers] : "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 = #(#[INTERFACE_DEF,"INTERFACE_DEF"], modifiers,IDENT,tp,ie,ib);} ; enumDefinition![AST modifiers] : "enum" IDENT // it might implement some interfaces... ic:implementsClause // now parse the body of the enum eb:enumBlock {#enumDefinition = #(#[ENUM_DEF,"ENUM_DEF"], modifiers,IDENT,ic,eb);} ; annotationDefinition![AST modifiers] : AT "interface" IDENT // now parse the body of the annotation ab:annotationBlock {#annotationDefinition = #(#[ANNOTATION_DEF,"ANNOTATION_DEF"], modifiers,IDENT,ab);} ; typeParameters {int currentLtLevel = 0;} : {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 = #(#[TYPE_PARAMETERS, "TYPE_PARAMETERS"], #typeParameters);} ; typeParameter : // I'm pretty sure Antlr generates the right thing here: (id:IDENT) ( options{generateAmbigWarnings=false;}: typeParameterBounds )? {#typeParameter = #(#[TYPE_PARAMETER,"TYPE_PARAMETER"], #typeParameter);} ; typeParameterBounds : "extends"! classOrInterfaceType[false] (BAND! classOrInterfaceType[false])* {#typeParameterBounds = #(#[TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS"], #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 class enumBlock : LCURLY! ( enumConstant ( options{greedy=true;}: COMMA! enumConstant )* ( COMMA! )? )? ( SEMI! ( classField | SEMI! )* )? RCURLY! {#enumBlock = #([OBJBLOCK, "OBJBLOCK"], #enumBlock);} ; // An annotation field annotationField! : 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 = #(#[ANNOTATION_FIELD_DEF,"ANNOTATION_FIELD_DEF"], mods, #(#[TYPE,"TYPE"],rt), i,amvi );} | v:variableDefinitions[#mods,#t] SEMI // variable {#annotationField = #v;} ) ) ; //An enum constant may have optional parameters and may have a //a class body enumConstant! : 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 constant enumConstantBlock : 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 initializer enumConstantField! : 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#enumConstantField = #v;} ) ) // "{ ... }" instance initializer | s4:compoundStatement {#enumConstantField = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ; // An interface can extend several other interfaces... interfaceExtends : ( e:"extends"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], #interfaceExtends);} ; // A class can implement several interfaces... implementsClause : ( i:"implements"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], #implementsClause);} ; // Now the various things that can be defined inside a class classField! : // method, constructor, or variable declaration mods:modifiers ( td:typeDefinitionInternal[#mods] {#classField = #td;} | (tp:typeParameters)? ( h:ctorHead s:constructorBody // constructor {#classField = #(#[CTOR_DEF,"CTOR_DEF"], 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#classField = #v;} ) ) ) // "static { ... }" class initializer | "static" s3:compoundStatement {#classField = #(#[STATIC_INIT,"STATIC_INIT"], s3);} // "{ ... }" instance initializer | s4:compoundStatement {#classField = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ; // Now the various things that can be defined inside a interface interfaceField! : // 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],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().dupList(t)] //dupList as this also copies siblings (like TYPE_ARGUMENTS) ( COMMA! variableDeclarator[getASTFactory().dupTree(mods), getASTFactory().dupList(t)] //dupList as this also copies siblings (like TYPE_ARGUMENTS) )* ; /** 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 throw throwsClause : "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 parameter parameterDeclarationList // 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 = #(#[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);} ; variableLengthParameterDeclaration! : pm:parameterModifier t:typeSpec[false] TRIPLE_DOT! id:IDENT pd:declaratorBrackets[#t] {#variableLengthParameterDeclaration = #(#[VARIABLE_PARAMETER_DEF,"VARIABLE_PARAMETER_DEF"], pm, #([TYPE,"TYPE"],pd), id);} ; parameterModifier //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 = #(#[MODIFIERS,"MODIFIERS"], #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 definitions compoundStatement : 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 | "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 : p:parameterDeclaration COLON! expression {#forEachClause = #(#[FOR_EACH_CLAUSE,"FOR_EACH_CLAUSE"], #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 : (statement)* {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} ; // The initializer for a for loop forInit // 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 block tryBlock : "try"^ compoundStatement (handler)* ( finallyClause )? ; finallyClause : "finally"^ compoundStatement ; // an exception handler handler : "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 expressions expression : 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^ 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/dec postfixExpression : 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 expression primaryExpression : 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 // 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... // this will also produce an ANTLR warning! // Unfortunately a syntactic predicate can only select one of // multiple alternatives on the same level, not break out of // an enclosing loop, which is why this ugly hack (a fake // empty alternative with always-false semantic predicate) // is necessary. )* ( options { // ARRAY_DECLARATOR here conflicts with INDEX_OP in // postfixExpression on LBRACK RBRACK. // We want to match [] here, so greedy. This overcomes // limitation of linear approximate lookahead. greedy=true; } : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} // if the input is valid, only the last IDENT may // have preceding typeArguments... rather hacky, this is... {if (#ta2 != null) astFactory.addASTChild(currentAST, #ta2);} {if (#ta2 == null) astFactory.addASTChild(currentAST, #ta1);} argList RPAREN! ) | ( options {greedy=true;} : lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+ )? ; /** 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"^ (typeArguments)? 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 | NUM_LONG | NUM_DOUBLE ; //---------------------------------------------------------------------------- // The Java scanner //---------------------------------------------------------------------------- class JavaLexer extends Lexer; options { exportVocab=Java; // call the vocabulary "Java" testLiterals=false; // don't automatically test for literals k=4; // four characters of lookahead charVocabulary='\u0003'..'\uFFFF'; // without inlining some bitset tests, couldn't do unicode; // I need to make ANTLR generate smaller bitsets; see // bottom of JavaLexer.java codeGenBitsetTestThreshold=20; } { /** flag for enabling the "assert" keyword */ private boolean assertEnabled = true; /** flag for enabling the "enum" keyword */ private boolean enumEnabled = true; /** Enable the "assert" keyword */ public void enableAssert(boolean shouldEnable) { assertEnabled = shouldEnable; } /** Query the "assert" keyword state */ public boolean isAssertEnabled() { return assertEnabled; } /** Enable the "enum" keyword */ public void enableEnum(boolean shouldEnable) { enumEnabled = shouldEnable; } /** Query the "enum" keyword state */ public boolean isEnumEnabled() { return enumEnabled; } } // OPERATORS QUESTION : '?' ; LPAREN : '(' ; RPAREN : ')' ; LBRACK : '[' ; RBRACK : ']' ; LCURLY : '{' ; RCURLY : '}' ; COLON : ':' ; COMMA : ',' ; //DOT : '.' ; ASSIGN : '=' ; EQUAL : "==" ; LNOT : '!' ; BNOT : '~' ; NOT_EQUAL : "!=" ; DIV : '/' ; DIV_ASSIGN : "/=" ; PLUS : '+' ; PLUS_ASSIGN : "+=" ; INC : "++" ; MINUS : '-' ; MINUS_ASSIGN : "-=" ; DEC : "--" ; STAR : '*' ; STAR_ASSIGN : "*=" ; MOD : '%' ; MOD_ASSIGN : "%=" ; SR : ">>" ; SR_ASSIGN : ">>=" ; BSR : ">>>" ; BSR_ASSIGN : ">>>=" ; GE : ">=" ; GT : ">" ; SL : "<<" ; SL_ASSIGN : "<<=" ; LE : "<=" ; LT : '<' ; BXOR : '^' ; BXOR_ASSIGN : "^=" ; BOR : '|' ; BOR_ASSIGN : "|=" ; LOR : "||" ; BAND : '&' ; BAND_ASSIGN : "&=" ; LAND : "&&" ; SEMI : ';' ; // Whitespace -- ignored WS : ( ' ' | '\t' | '\f' // handle newlines | ( options {generateAmbigWarnings=false;} : "\r\n" // Evil DOS | '\r' // Macintosh | '\n' // Unix (the right way) ) { newline(); } )+ { _ttype = Token.SKIP; } ; // Single-line comments SL_COMMENT : "//" (~('\n'|'\r'))* ('\n'|'\r'('\n')?) {$setType(Token.SKIP); newline();} ; // multiple-line comments ML_COMMENT : "/*" ( /* '\r' '\n' can be matched in one alternative or by matching '\r' in one iteration and '\n' in another. I am trying to handle any flavor of newline that comes in, but the language that allows both "\r\n" and "\r" and "\n" to all be valid newline is ambiguous. Consequently, the resulting grammar must be ambiguous. I'm shutting this warning off. */ options { generateAmbigWarnings=false; } : { LA(2)!='/' }? '*' | '\r' '\n' {newline();} | '\r' {newline();} | '\n' {newline();} | ~('*'|'\n'|'\r') )* "*/" {$setType(Token.SKIP);} ; // character literals CHAR_LITERAL : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' ; // string literals STRING_LITERAL : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' ; // escape sequence -- note that this is protected; it can only be called // from another lexer rule -- it will not ever directly return a token to // the parser // There are various ambiguities hushed in this rule. The optional // '0'...'9' digit matches should be matched here rather than letting // them go back to STRING_LITERAL to be matched. ANTLR does the // right thing by matching immediately; hence, it's ok to shut off // the FOLLOW ambig warnings. protected ESC : '\\' ( 'n' | 'r' | 't' | 'b' | 'f' | '"' | '\'' | '\\' | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT | '0'..'3' ( options { warnWhenFollowAmbig = false; } : '0'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? )? | '4'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? ) ; // hexadecimal digit (again, note it's protected!) protected HEX_DIGIT : ('0'..'9'|'A'..'F'|'a'..'f') ; // a dummy rule to force vocabulary to be all characters (except special // ones that ANTLR uses internally (0 to 2) protected VOCAB : '\3'..'\377' ; // an identifier. Note that testLiterals is set to true! This means // that after we match the rule, we look in the literals table to see // if it's a literal or really an identifer IDENT options {testLiterals=true;} : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* { // check if "assert" keyword is enabled if (assertEnabled && "assert".equals($getText)) { $setType(LITERAL_assert); // set token type for the rule in the parser } // check if "enum" keyword is enabled if (enumEnabled && "enum".equals($getText)) { $setType(LITERAL_enum); // set token type for the rule in the parser } } ; // a numeric literal NUM_INT {boolean isDecimal=false; Token t=null;} : '.' {_ttype = DOT;} ( (('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? { if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } }) | // JDK 1.5 token for variable length arguments (".." {_ttype = TRIPLE_DOT;}) )? | ( '0' {isDecimal = true;} // special case for just '0' ( ('x'|'X') ( // hex // the 'e'|'E' and float suffix stuff look // like hex digits, hence the (...)+ doesn't // know when to stop: ambig. ANTLR resolves // it correctly by matching immediately. It // is therefor ok to hush warning. options { warnWhenFollowAmbig=false; } : HEX_DIGIT )+ | //float or double with leading zero (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ | ('0'..'7')+ // octal )? | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal ) ( ('l'|'L') { _ttype = NUM_LONG; } // only check to see if it's a float if looks like decimal so far | {isDecimal}? ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? | f4:FLOAT_SUFFIX {t=f4;} ) { if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } } )? ; // JDK 1.5 token for annotations and their declarations AT : '@' ; // a couple protected methods to assist in matching floating point numbers protected EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; protected FLOAT_SUFFIX : 'f'|'F'|'d'|'D' ;antlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-test/0000775000175000017500000000000012165015352024510 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-test/src/0000775000175000017500000000000012165015352025277 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-test/src/main/0000775000175000017500000000000012165015352026223 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-test/src/main/antlr/0000775000175000017500000000000012165015352027343 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-test/src/main/antlr/java15.g0000664000175000017500000014316510647361554030627 0ustar ebourgebourg/** Java 1.5 Recognizer /** Java 1.5 Recognizer * * Run 'java Main [-showtree] directory-full-of-java-files' * * [The -showtree option pops up a Swing frame that shows * the AST constructed from the parser.] * * Run 'java Main ' * * Contributing authors: * John Mitchell johnm@non.net * Terence Parr parrt@magelang.com * John Lilley jlilley@empathy.com * Scott Stanchfield thetick@magelang.com * Markus Mohnen mohnen@informatik.rwth-aachen.de * Peter Williams pete.williams@sun.com * Allan Jacobs Allan.Jacobs@eng.sun.com * Steve Messick messick@redhills.com * John Pybus john@pybus.org * * Version 1.00 December 9, 1997 -- initial release * Version 1.01 December 10, 1997 * fixed bug in octal def (0..7 not 0..8) * Version 1.10 August 1998 (parrt) * added tree construction * fixed definition of WS,comments for mac,pc,unix newlines * added unary plus * Version 1.11 (Nov 20, 1998) * Added "shutup" option to turn off last ambig warning. * Fixed inner class def to allow named class defs as statements * synchronized requires compound not simple statement * add [] after builtInType DOT class in primaryExpression * "const" is reserved but not valid..removed from modifiers * Version 1.12 (Feb 2, 1999) * Changed LITERAL_xxx to xxx in tree grammar. * Updated java.g to use tokens {...} now for 2.6.0 (new feature). * * Version 1.13 (Apr 23, 1999) * Didn't have (stat)? for else clause in tree parser. * Didn't gen ASTs for interface extends. Updated tree parser too. * Updated to 2.6.0. * Version 1.14 (Jun 20, 1999) * Allowed final/abstract on local classes. * Removed local interfaces from methods * Put instanceof precedence where it belongs...in relationalExpr * It also had expr not type as arg; fixed it. * Missing ! on SEMI in classBlock * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). * fixed: didn't like Object[].class in parser or tree parser * Version 1.15 (Jun 26, 1999) * Screwed up rule with instanceof in it. :( Fixed. * Tree parser didn't like (expr).something; fixed. * Allowed multiple inheritance in tree grammar. oops. * Version 1.16 (August 22, 1999) * Extending an interface built a wacky tree: had extra EXTENDS. * Tree grammar didn't allow multiple superinterfaces. * Tree grammar didn't allow empty var initializer: {} * Version 1.17 (October 12, 1999) * ESC lexer rule allowed 399 max not 377 max. * java.tree.g didn't handle the expression of synchronized * statements. * Version 1.18 (August 12, 2001) * Terence updated to Java 2 Version 1.3 by * observing/combining work of Allan Jacobs and Steve * Messick. Handles 1.3 src. Summary: * o primary didn't include boolean.class kind of thing * o constructor calls parsed explicitly now: * see explicitConstructorInvocation * o add strictfp modifier * o missing objBlock after new expression in tree grammar * o merged local class definition alternatives, moved after declaration * o fixed problem with ClassName.super.field * o reordered some alternatives to make things more efficient * o long and double constants were not differentiated from int/float * o whitespace rule was inefficient: matched only one char * o add an examples directory with some nasty 1.3 cases * o made Main.java use buffered IO and a Reader for Unicode support * o supports UNICODE? * Using Unicode charVocabulay makes code file big, but only * in the bitsets at the end. I need to make ANTLR generate * unicode bitsets more efficiently. * Version 1.19 (April 25, 2002) * Terence added in nice fixes by John Pybus concerning floating * constants and problems with super() calls. John did a nice * reorg of the primary/postfix expression stuff to read better * and makes f.g.super() parse properly (it was METHOD_CALL not * a SUPER_CTOR_CALL). Also: * * o "finally" clause was a root...made it a child of "try" * o Added stuff for asserts too for Java 1.4, but *commented out* * as it is not backward compatible. * * Version 1.20 (October 27, 2002) * * Terence ended up reorging John Pybus' stuff to * remove some nondeterminisms and some syntactic predicates. * Note that the grammar is stricter now; e.g., this(...) must * be the first statement. * * Trinary ?: operator wasn't working as array name: * (isBig ? bigDigits : digits)[i]; * * Checked parser/tree parser on source for * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, * and the 110k-line jGuru server source. * * Version 1.21 (October 17, 2003) * Fixed lots of problems including: * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g * He found a problem/fix with floating point that start with 0 * Ray also fixed problem that (int.class) was not recognized. * Thorsten van Ellen noticed that \n are allowed incorrectly in strings. * TJP fixed CHAR_LITERAL analogously. * * Version 1.21.2 (March, 2003) * Changes by Matt Quail to support generics (as per JDK1.5/JSR14) * Notes: * o We only allow the "extends" keyword and not the "implements" * keyword, since thats what JSR14 seems to imply. * o Thanks to Monty Zukowski for his help on the antlr-interest * mail list. * o Thanks to Alan Eliasen for testing the grammar over his * Fink source base * * Version 1.22 (July, 2004) * Changes by Michael Studman to support Java 1.5 language extensions * Notes: * o Added support for annotations types * o Finished off Matt Quail's generics enhancements to support bound type arguments * o Added support for new for statement syntax * o Added support for static import syntax * o Added support for enum types * o Tested against JDK 1.5 source base and source base of jdigraph project * o Thanks to Matt Quail for doing the hard part by doing most of the generics work * * Version 1.22.1 (July 28, 2004) * Bug/omission fixes for Java 1.5 language support * o Fixed tree structure bug with classOrInterface - thanks to Pieter Vangorpto for * spotting this * o Fixed bug where incorrect handling of SR and BSR tokens would cause type * parameters to be recognised as type arguments. * o Enabled type parameters on constructors, annotations on enum constants * and package definitions * o Fixed problems when parsing if ((char.class.equals(c))) {} - solution by Matt Quail at Cenqua * * Version 1.22.2 (July 28, 2004) * Slight refactoring of Java 1.5 language support * o Refactored for/"foreach" productions so that original literal "for" literal * is still used but the for sub-clauses vary by token type * o Fixed bug where type parameter was not included in generic constructor's branch of AST * * Version 1.22.3 (August 26, 2004) * Bug fixes as identified by Michael Stahl; clean up of tabs/spaces * and other refactorings * o Fixed typeParameters omission in identPrimary and newStatement * o Replaced GT reconcilliation code with simple semantic predicate * o Adapted enum/assert keyword checking support from Michael Stahl's java15 grammar * o Refactored typeDefinition production and field productions to reduce duplication * * Version 1.22.4 (October 21, 2004) * Small bux fixes * o Added typeArguments to explicitConstructorInvocation, e.g. new MyParameterised() * o Added typeArguments to postfixExpression productions for anonymous inner class super * constructor invocation, e.g. new Outer().super() * o Fixed bug in array declarations identified by Geoff Roy * * Version 1.22.5 (January 03, 2005) * Small change to tree structure * o Flattened classOrInterfaceType tree so IDENT no longer has children. TYPE_ARGUMENTS are now * always siblings of IDENT rather than children. Fully.qualified.names trees now * look a little less clean when TYPE_ARGUMENTS are present though. * * This grammar is in the PUBLIC DOMAIN */ 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; VARIABLE_PARAMETER_DEF; STATIC_IMPORT; ENUM_DEF; ENUM_CONSTANT_DEF; FOR_EACH_CLAUSE; ANNOTATION_DEF; ANNOTATIONS; ANNOTATION; ANNOTATION_MEMBER_VALUE_PAIR; ANNOTATION_FIELD_DEF; ANNOTATION_ARRAY_INIT; TYPE_ARGUMENTS; TYPE_ARGUMENT; TYPE_PARAMETERS; TYPE_PARAMETER; WILDCARD_TYPE; TYPE_UPPER_BOUNDS; TYPE_LOWER_BOUNDS; } { /** * Counts the number of LT seen in the typeArguments production. * It is used in semantic predicates to ensure we have seen * enough closing '>' characters; which actually may have been * either GT, SR or BSR tokens. */ private int ltCounter = 0; } // Compilation Unit: In Java, this is a single file. This is the start // rule for this parser compilationUnit : // A compilation unit starts with an optional package definition ( (annotations "package")=> 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! ; // Package statement: optional annotations followed by "package" then the package identifier. packageDefinition options {defaultErrorHandler = true;} // let ANTLR handle errors : annotations p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! ; // Import statement: import followed by a package or class name importDefinition options {defaultErrorHandler = true;} { boolean isStatic = false; } : i:"import"^ {#i.setType(IMPORT);} ( "static"! {#i.setType(STATIC_IMPORT);} )? identifierStar SEMI! ; // A type definition is either a class, interface, enum or annotation with possible additional semis. typeDefinition options {defaultErrorHandler = true;} : m:modifiers! typeDefinitionInternal[#m] | SEMI! ; // Protected type definitions production for reuse in other productions protected typeDefinitionInternal[AST mods] : classDefinition[#mods] // inner class | interfaceDefinition[#mods] // inner interface | enumDefinition[#mods] // inner enum | annotationDefinition[#mods] // inner annotation ; // 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 either: // - possible brackets afterwards // (which would make it an array type). // - generic type arguments after classTypeSpec[boolean addImagNode] : classOrInterfaceType[false] (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )* { if ( addImagNode ) { #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); } } ; // A non-built in type name, with possible type parameters classOrInterfaceType[boolean addImagNode] : IDENT (typeArguments)? (options{greedy=true;}: // match as many as possible DOT^ IDENT (typeArguments)? )* { if ( addImagNode ) { #classOrInterfaceType = #(#[TYPE,"TYPE"], #classOrInterfaceType); } } ; // A specialised form of typeSpec where built in types must be arrays typeArgumentSpec : classTypeSpec[true] | builtInTypeArraySpec[true] ; // A generic type argument is a class type, a possibly bounded wildcard type or a built-in type array typeArgument : ( typeArgumentSpec | wildcardType ) {#typeArgument = #(#[TYPE_ARGUMENT,"TYPE_ARGUMENT"], #typeArgument);} ; // Wildcard type indicating all types (with possible constraint) wildcardType : q:QUESTION^ {#q.setType(WILDCARD_TYPE);} (("extends" | "super")=> typeArgumentBounds)? ; // Type arguments to a class or interface type typeArguments {int currentLtLevel = 0;} : {currentLtLevel = ltCounter;} LT! {ltCounter++;} typeArgument (options{greedy=true;}: // match as many as possible {inputState.guessing !=0 || ltCounter == currentLtLevel + 1}? COMMA! typeArgument )* ( // turn warning off since Antlr generates the right code, // plus we have our semantic predicate below options{generateAmbigWarnings=false;}: typeArgumentsOrParametersEnd )? // make sure we have gobbled up enough '>' characters // if we are at the "top level" of nested typeArgument productions {(currentLtLevel != 0) || ltCounter == currentLtLevel}? {#typeArguments = #(#[TYPE_ARGUMENTS, "TYPE_ARGUMENTS"], #typeArguments);} ; // this gobbles up *some* amount of '>' characters, and counts how many // it gobbled. protected typeArgumentsOrParametersEnd : GT! {ltCounter-=1;} | SR! {ltCounter-=2;} | BSR! {ltCounter-=3;} ; // Restriction on wildcard types based on super class or derrived class typeArgumentBounds {boolean isUpperBounds = false;} : ( "extends"! {isUpperBounds=true;} | "super"! ) classOrInterfaceType[false] { if (isUpperBounds) { #typeArgumentBounds = #(#[TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS"], #typeArgumentBounds); } else { #typeArgumentBounds = #(#[TYPE_LOWER_BOUNDS,"TYPE_LOWER_BOUNDS"], #typeArgumentBounds); } } ; // A builtin type array specification is a builtin type with brackets afterwards builtInTypeArraySpec[boolean addImagNode] : builtInType (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )+ { if ( addImagNode ) { #builtInTypeArraySpec = #(#[TYPE,"TYPE"], #builtInTypeArraySpec); } } ; // A builtin type specification is a builtin type with possible brackets // afterwards (which would make it an array type). builtInTypeSpec[boolean addImagNode] : builtInType (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )* { if ( addImagNode ) { #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); } } ; // A type name. which is either a (possibly qualified and parameterized) // class name or a primitive (builtin) type type : classOrInterfaceType[false] | 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 IDENTS identifier : 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 desires modifiers : ( //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 = #([MODIFIERS, "MODIFIERS"], #modifiers);} ; // modifiers for Java classes, interfaces, class/instance vars and methods modifier : "private" | "public" | "protected" | "static" | "transient" | "final" | "abstract" | "native" | "threadsafe" | "synchronized" | "volatile" | "strictfp" ; annotation! : AT! i:identifier ( LPAREN! ( args:annotationArguments )? RPAREN! )? {#annotation = #(#[ANNOTATION,"ANNOTATION"], i, args);} ; annotations : (annotation)* {#annotations = #([ANNOTATIONS, "ANNOTATIONS"], #annotations);} ; annotationArguments : annotationMemberValueInitializer | anntotationMemberValuePairs ; anntotationMemberValuePairs : annotationMemberValuePair ( COMMA! annotationMemberValuePair )* ; annotationMemberValuePair! : i:IDENT ASSIGN! v:annotationMemberValueInitializer {#annotationMemberValuePair = #(#[ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR"], 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! : ( "extends" c:classOrInterfaceType[false] )? {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],c);} ; // Definition of a Java class classDefinition![AST modifiers] : "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 = #(#[CLASS_DEF,"CLASS_DEF"], modifiers,IDENT,tp,sc,ic,cb);} ; // Definition of a Java Interface interfaceDefinition![AST modifiers] : "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 = #(#[INTERFACE_DEF,"INTERFACE_DEF"], modifiers,IDENT,tp,ie,ib);} ; enumDefinition![AST modifiers] : "enum" IDENT // it might implement some interfaces... ic:implementsClause // now parse the body of the enum eb:enumBlock {#enumDefinition = #(#[ENUM_DEF,"ENUM_DEF"], modifiers,IDENT,ic,eb);} ; annotationDefinition![AST modifiers] : AT "interface" IDENT // now parse the body of the annotation ab:annotationBlock {#annotationDefinition = #(#[ANNOTATION_DEF,"ANNOTATION_DEF"], modifiers,IDENT,ab);} ; typeParameters {int currentLtLevel = 0;} : {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 = #(#[TYPE_PARAMETERS, "TYPE_PARAMETERS"], #typeParameters);} ; typeParameter : // I'm pretty sure Antlr generates the right thing here: (id:IDENT) ( options{generateAmbigWarnings=false;}: typeParameterBounds )? {#typeParameter = #(#[TYPE_PARAMETER,"TYPE_PARAMETER"], #typeParameter);} ; typeParameterBounds : "extends"! classOrInterfaceType[false] (BAND! classOrInterfaceType[false])* {#typeParameterBounds = #(#[TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS"], #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 class enumBlock : LCURLY! ( enumConstant ( options{greedy=true;}: COMMA! enumConstant )* ( COMMA! )? )? ( SEMI! ( classField | SEMI! )* )? RCURLY! {#enumBlock = #([OBJBLOCK, "OBJBLOCK"], #enumBlock);} ; // An annotation field annotationField! : 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 = #(#[ANNOTATION_FIELD_DEF,"ANNOTATION_FIELD_DEF"], mods, #(#[TYPE,"TYPE"],rt), i,amvi );} | v:variableDefinitions[#mods,#t] SEMI // variable {#annotationField = #v;} ) ) ; //An enum constant may have optional parameters and may have a //a class body enumConstant! : 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 constant enumConstantBlock : 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 initializer enumConstantField! : 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#enumConstantField = #v;} ) ) // "{ ... }" instance initializer | s4:compoundStatement {#enumConstantField = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ; // An interface can extend several other interfaces... interfaceExtends : ( e:"extends"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], #interfaceExtends);} ; // A class can implement several interfaces... implementsClause : ( i:"implements"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], #implementsClause);} ; // Now the various things that can be defined inside a class classField! : // method, constructor, or variable declaration mods:modifiers ( td:typeDefinitionInternal[#mods] {#classField = #td;} | (tp:typeParameters)? ( h:ctorHead s:constructorBody // constructor {#classField = #(#[CTOR_DEF,"CTOR_DEF"], 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#classField = #v;} ) ) ) // "static { ... }" class initializer | "static" s3:compoundStatement {#classField = #(#[STATIC_INIT,"STATIC_INIT"], s3);} // "{ ... }" instance initializer | s4:compoundStatement {#classField = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ; // Now the various things that can be defined inside a interface interfaceField! : // 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],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().dupList(t)] //dupList as this also copies siblings (like TYPE_ARGUMENTS) ( COMMA! variableDeclarator[getASTFactory().dupTree(mods), getASTFactory().dupList(t)] //dupList as this also copies siblings (like TYPE_ARGUMENTS) )* ; /** 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 throw throwsClause : "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 parameter parameterDeclarationList // 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 = #(#[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);} ; variableLengthParameterDeclaration! : pm:parameterModifier t:typeSpec[false] TRIPLE_DOT! id:IDENT pd:declaratorBrackets[#t] {#variableLengthParameterDeclaration = #(#[VARIABLE_PARAMETER_DEF,"VARIABLE_PARAMETER_DEF"], pm, #([TYPE,"TYPE"],pd), id);} ; parameterModifier //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 = #(#[MODIFIERS,"MODIFIERS"], #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 definitions compoundStatement : 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 | "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 : p:parameterDeclaration COLON! expression {#forEachClause = #(#[FOR_EACH_CLAUSE,"FOR_EACH_CLAUSE"], #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 : (statement)* {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} ; // The initializer for a for loop forInit // 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 block tryBlock : "try"^ compoundStatement (handler)* ( finallyClause )? ; finallyClause : "finally"^ compoundStatement ; // an exception handler handler : "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 expressions expression : 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^ 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/dec postfixExpression : 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 expression primaryExpression : 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 // 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... // this will also produce an ANTLR warning! // Unfortunately a syntactic predicate can only select one of // multiple alternatives on the same level, not break out of // an enclosing loop, which is why this ugly hack (a fake // empty alternative with always-false semantic predicate) // is necessary. )* ( options { // ARRAY_DECLARATOR here conflicts with INDEX_OP in // postfixExpression on LBRACK RBRACK. // We want to match [] here, so greedy. This overcomes // limitation of linear approximate lookahead. greedy=true; } : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} // if the input is valid, only the last IDENT may // have preceding typeArguments... rather hacky, this is... {if (#ta2 != null) astFactory.addASTChild(currentAST, #ta2);} {if (#ta2 == null) astFactory.addASTChild(currentAST, #ta1);} argList RPAREN! ) | ( options {greedy=true;} : lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+ )? ; /** 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"^ (typeArguments)? 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 | NUM_LONG | NUM_DOUBLE ; //---------------------------------------------------------------------------- // The Java scanner //---------------------------------------------------------------------------- class JavaLexer extends Lexer; options { exportVocab=Java; // call the vocabulary "Java" testLiterals=false; // don't automatically test for literals k=4; // four characters of lookahead charVocabulary='\u0003'..'\uFFFF'; // without inlining some bitset tests, couldn't do unicode; // I need to make ANTLR generate smaller bitsets; see // bottom of JavaLexer.java codeGenBitsetTestThreshold=20; } { /** flag for enabling the "assert" keyword */ private boolean assertEnabled = true; /** flag for enabling the "enum" keyword */ private boolean enumEnabled = true; /** Enable the "assert" keyword */ public void enableAssert(boolean shouldEnable) { assertEnabled = shouldEnable; } /** Query the "assert" keyword state */ public boolean isAssertEnabled() { return assertEnabled; } /** Enable the "enum" keyword */ public void enableEnum(boolean shouldEnable) { enumEnabled = shouldEnable; } /** Query the "enum" keyword state */ public boolean isEnumEnabled() { return enumEnabled; } } // OPERATORS QUESTION : '?' ; LPAREN : '(' ; RPAREN : ')' ; LBRACK : '[' ; RBRACK : ']' ; LCURLY : '{' ; RCURLY : '}' ; COLON : ':' ; COMMA : ',' ; //DOT : '.' ; ASSIGN : '=' ; EQUAL : "==" ; LNOT : '!' ; BNOT : '~' ; NOT_EQUAL : "!=" ; DIV : '/' ; DIV_ASSIGN : "/=" ; PLUS : '+' ; PLUS_ASSIGN : "+=" ; INC : "++" ; MINUS : '-' ; MINUS_ASSIGN : "-=" ; DEC : "--" ; STAR : '*' ; STAR_ASSIGN : "*=" ; MOD : '%' ; MOD_ASSIGN : "%=" ; SR : ">>" ; SR_ASSIGN : ">>=" ; BSR : ">>>" ; BSR_ASSIGN : ">>>=" ; GE : ">=" ; GT : ">" ; SL : "<<" ; SL_ASSIGN : "<<=" ; LE : "<=" ; LT : '<' ; BXOR : '^' ; BXOR_ASSIGN : "^=" ; BOR : '|' ; BOR_ASSIGN : "|=" ; LOR : "||" ; BAND : '&' ; BAND_ASSIGN : "&=" ; LAND : "&&" ; SEMI : ';' ; // Whitespace -- ignored WS : ( ' ' | '\t' | '\f' // handle newlines | ( options {generateAmbigWarnings=false;} : "\r\n" // Evil DOS | '\r' // Macintosh | '\n' // Unix (the right way) ) { newline(); } )+ { _ttype = Token.SKIP; } ; // Single-line comments SL_COMMENT : "//" (~('\n'|'\r'))* ('\n'|'\r'('\n')?) {$setType(Token.SKIP); newline();} ; // multiple-line comments ML_COMMENT : "/*" ( /* '\r' '\n' can be matched in one alternative or by matching '\r' in one iteration and '\n' in another. I am trying to handle any flavor of newline that comes in, but the language that allows both "\r\n" and "\r" and "\n" to all be valid newline is ambiguous. Consequently, the resulting grammar must be ambiguous. I'm shutting this warning off. */ options { generateAmbigWarnings=false; } : { LA(2)!='/' }? '*' | '\r' '\n' {newline();} | '\r' {newline();} | '\n' {newline();} | ~('*'|'\n'|'\r') )* "*/" {$setType(Token.SKIP);} ; // character literals CHAR_LITERAL : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' ; // string literals STRING_LITERAL : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' ; // escape sequence -- note that this is protected; it can only be called // from another lexer rule -- it will not ever directly return a token to // the parser // There are various ambiguities hushed in this rule. The optional // '0'...'9' digit matches should be matched here rather than letting // them go back to STRING_LITERAL to be matched. ANTLR does the // right thing by matching immediately; hence, it's ok to shut off // the FOLLOW ambig warnings. protected ESC : '\\' ( 'n' | 'r' | 't' | 'b' | 'f' | '"' | '\'' | '\\' | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT | '0'..'3' ( options { warnWhenFollowAmbig = false; } : '0'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? )? | '4'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? ) ; // hexadecimal digit (again, note it's protected!) protected HEX_DIGIT : ('0'..'9'|'A'..'F'|'a'..'f') ; // a dummy rule to force vocabulary to be all characters (except special // ones that ANTLR uses internally (0 to 2) protected VOCAB : '\3'..'\377' ; // an identifier. Note that testLiterals is set to true! This means // that after we match the rule, we look in the literals table to see // if it's a literal or really an identifer IDENT options {testLiterals=true;} : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* { // check if "assert" keyword is enabled if (assertEnabled && "assert".equals($getText)) { $setType(LITERAL_assert); // set token type for the rule in the parser } // check if "enum" keyword is enabled if (enumEnabled && "enum".equals($getText)) { $setType(LITERAL_enum); // set token type for the rule in the parser } } ; // a numeric literal NUM_INT {boolean isDecimal=false; Token t=null;} : '.' {_ttype = DOT;} ( (('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? { if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } }) | // JDK 1.5 token for variable length arguments (".." {_ttype = TRIPLE_DOT;}) )? | ( '0' {isDecimal = true;} // special case for just '0' ( ('x'|'X') ( // hex // the 'e'|'E' and float suffix stuff look // like hex digits, hence the (...)+ doesn't // know when to stop: ambig. ANTLR resolves // it correctly by matching immediately. It // is therefor ok to hush warning. options { warnWhenFollowAmbig=false; } : HEX_DIGIT )+ | //float or double with leading zero (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ | ('0'..'7')+ // octal )? | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal ) ( ('l'|'L') { _ttype = NUM_LONG; } // only check to see if it's a float if looks like decimal so far | {isDecimal}? ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? | f4:FLOAT_SUFFIX {t=f4;} ) { if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } } )? ; // JDK 1.5 token for annotations and their declarations AT : '@' ; // a couple protected methods to assist in matching floating point numbers protected EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; protected FLOAT_SUFFIX : 'f'|'F'|'d'|'D' ;antlr-maven-plugin-2.2/src/test/resources/unit/java-grammar-test/java-grammar-test-plugin-config.xml0000664000175000017500000000410510773161441033317 0ustar ebourgebourg 4.0.0 java-grammar.test java-grammar-test jar 1.0-SNAPSHOT 2006 Maven Antlr Plugin Java-grammar Test http://mojo.codehaus.org antlr antlr 2.7.7 org.codehaus.mojo antlr-maven-plugin ${basedir}/target/test/unit/java-grammar-test/target/generated-sources/antlr ${basedir}/src/test/resources/unit/java-grammar-test/src/main/antlr java15.g antlr-maven-plugin-2.2/src/test/java/0000775000175000017500000000000012165015351017115 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/java/org/0000775000175000017500000000000012165015351017704 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/java/org/codehaus/0000775000175000017500000000000012165015351021477 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/0000775000175000017500000000000012165015351022443 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/0000775000175000017500000000000012165015351023563 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/AntlrPluginTest.java0000664000175000017500000001743610773161441027545 0ustar ebourgebourgpackage org.codehaus.mojo.antlr; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.IOException; import java.util.ArrayList; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.repository.DefaultArtifactRepositoryFactory; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.plugin.Mojo; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.plugin.testing.stubs.StubArtifactRepository; import org.apache.maven.project.MavenProject; import org.codehaus.mojo.antlr.stubs.DependencyArtifactStubFactory; import org.codehaus.mojo.antlr.stubs.DependencyProjectStub; import org.codehaus.plexus.util.FileUtils; /** * Unit tests of Antlr plugin * * @author Vincent Siveton * @version $Id: AntlrPluginTest.java 6588 2008-03-28 12:22:57Z bentmann $ */ public class AntlrPluginTest extends AbstractMojoTestCase { protected File testDir; protected DependencyArtifactStubFactory artifactStubFactory; /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { // required for mojo lookups to work super.setUp(); testDir = new File( getBasedir() ); testDir = new File( testDir, "target" ); testDir = new File( testDir, "unit-tests" ); testDir = new File( testDir, "antlr-tests" ); removeDirectory( testDir ); assertFalse( testDir.exists() ); artifactStubFactory = new DependencyArtifactStubFactory( this.testDir, false ); } /** * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { if ( testDir != null ) { try { removeDirectory( testDir ); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); fail( "Trying to remove directory:" + testDir + "\r\n" + e.toString() ); } assertFalse( testDir.exists() ); testDir = null; } artifactStubFactory = null; } /** * Method to test Antlr generation * * @throws Exception */ public void testJavaGrammar() throws Exception { File testPom = new File( getBasedir(), "src/test/resources/unit/java-grammar-test/java-grammar-test-plugin-config.xml" ); AntlrPlugin mojo = (AntlrPlugin) lookupMojo( testPom, true ); mojo.execute(); File outputDir = new File( getBasedir(), "target/test/unit/java-grammar-test/target/generated-sources/antlr/" ); assertTrue( new File( outputDir, "JavaLexer.java" ).exists() ); assertTrue( new File( outputDir, "JavaRecognizer.java" ).exists() ); assertTrue( new File( outputDir, "JavaTokenTypes.java" ).exists() ); assertTrue( new File( outputDir, "JavaTokenTypes.txt" ).exists() ); } /** * Method to test Antlr generation * * @throws Exception */ public void testJavaGrammarInheritance() throws Exception { File testPom = new File( getBasedir(), "src/test/resources/unit/java-grammar-inheritance-test/java-grammar-inheritance-test-plugin-config.xml" ); AntlrPlugin mojo = (AntlrPlugin) lookupMojo( testPom, true ); mojo.execute(); File outputDir = new File( getBasedir(), "target/test/unit/java-grammar-inheritance-test/target/generated-sources/antlr/" ); assertTrue( outputDir.exists() ); assertTrue( new File( outputDir, "GnuCEmitter.java" ).exists() ); assertTrue( new File( outputDir, "GnuCEmitterTokenTypes.java" ).exists() ); assertTrue( new File( outputDir, "GnuCLexer.java" ).exists() ); assertTrue( new File( outputDir, "GnuCLexerTokenTypes.java" ).exists() ); assertTrue( new File( outputDir, "GnuCParser.java" ).exists() ); assertTrue( new File( outputDir, "GNUCTokenTypes.java" ).exists() ); assertTrue( new File( outputDir, "GnuCTreeParser.java" ).exists() ); assertTrue( new File( outputDir, "GnuCTreeParserTokenTypes.java" ).exists() ); assertTrue( new File( outputDir, "StdCLexer.java" ).exists() ); assertTrue( new File( outputDir, "StdCParser.java" ).exists() ); assertTrue( new File( outputDir, "STDCTokenTypes.java" ).exists() ); } public void testMissingAntlrDependency() throws Exception { try { File testPom = new File( getBasedir(), "src/test/resources/unit/no-antlr-dep/no-antlr-dep-test-plugin-config.xml" ); AntlrPlugin mojo = (AntlrPlugin) lookupMojo( testPom, false ); mojo.execute(); fail( "was expecting failure due to missing antlr dep" ); } catch ( AntlrPlugin.NoAntlrDependencyDefinedException expected ) { // expected behavior } } protected Mojo lookupMojo(File pom, boolean addAntlrDep) throws Exception { AntlrPlugin mojo = (AntlrPlugin) super.lookupMojo( "generate", pom ); assertNotNull( mojo ); assertNotNull( mojo.project ); MavenProject project = mojo.project; if ( addAntlrDep ) { Artifact antlrArtifact = artifactStubFactory.createArtifact( "antlr", "antlr", "2.7.7" ); resolveArtifact( antlrArtifact ); ArrayList artifacts = new ArrayList(); artifacts.add( antlrArtifact ); ( ( DependencyProjectStub ) project ).setCompileArtifacts( artifacts ); } return mojo; } protected void resolveArtifact(Artifact artifact) throws Exception { if ( artifact.isResolved() ) { return; } File localRepoDir = new File( new File( new File( getBasedir(), "target" ), "test" ), "stub-repo" ); ArtifactRepository localRepository = new StubArtifactRepository( localRepoDir.getAbsolutePath() ); DefaultArtifactRepositoryFactory artifactRepositoryFactory = new DefaultArtifactRepositoryFactory(); ArtifactRepository centralRepo = artifactRepositoryFactory.createArtifactRepository( "central-stub", "http://repo1.maven.org/maven2/", new DefaultRepositoryLayout(), new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE ), new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE ) ); ArrayList remoteRepositories = new ArrayList(); remoteRepositories.add( centralRepo ); ArtifactResolver artifactResolver = ( ArtifactResolver ) super.lookup( "org.apache.maven.artifact.resolver.ArtifactResolver" ); artifactResolver.resolve( artifact, remoteRepositories, localRepository ); artifact.setResolved( true ); } public static void removeDirectory( File dir ) throws IOException { FileUtils.deleteDirectory( dir ); } } antlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/0000775000175000017500000000000012165015351024723 5ustar ebourgebourgantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/DependencyProjectStub.java0000664000175000017500000005155510773161441032051 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.stubs; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.IOException; import java.io.Writer; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Build; import org.apache.maven.model.CiManagement; import org.apache.maven.model.Contributor; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.Developer; import org.apache.maven.model.DistributionManagement; import org.apache.maven.model.IssueManagement; import org.apache.maven.model.License; import org.apache.maven.model.MailingList; import org.apache.maven.model.Model; import org.apache.maven.model.Organization; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginManagement; import org.apache.maven.model.Prerequisites; import org.apache.maven.model.Reporting; import org.apache.maven.model.Resource; import org.apache.maven.model.Scm; import org.apache.maven.plugin.testing.stubs.DefaultArtifactHandlerStub; import org.apache.maven.project.MavenProject; import org.apache.maven.project.artifact.InvalidDependencyVersionException; import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.util.xml.Xpp3Dom; /** * DependencyProjectStub implementation * * @author Steve Ebersole */ public class DependencyProjectStub extends MavenProject { private String groupId; private String artifactId; private String name; private Model model; private MavenProject parent; private List dependencies; private File file; private List collectedProjects; private List attachedArtifacts; private List compileSourceRoots; private List testCompileSourceRoots; private List scriptSourceRoots; private List pluginArtifactRepositories; // private ArtifactRepository releaseArtifactRepository; // private ArtifactRepository snapshotArtifactRepository; private List activeProfiles; private Set dependencyArtifacts; private DependencyManagement dependencyManagement; private Artifact artifact; // private Map artifactMap; private Model originalModel; // private Map pluginArtifactMap; // private Map reportArtifactMap; // private Map extensionArtifactMap; // private Map projectReferences; // private Build buildOverlay; private boolean executionRoot; private List compileArtifacts; private List compileDependencies; private List systemDependencies; private List testClasspathElements; private List testDependencies; private List systemClasspathElements; private List systemArtifacts; private List testArtifacts; private List runtimeArtifacts; private List runtimeDependencies; private List runtimeClasspathElements; private String modelVersion; private String packaging; private String inceptionYear; private String url; private String description; private String version; private String defaultGoal; private Set artifacts; public DependencyProjectStub() { super( (Model) null ); } // kinda dangerous... public DependencyProjectStub( Model model ) { // super(model); super( (Model) null ); } // kinda dangerous... public DependencyProjectStub( MavenProject project ) { // super(project); super( (Model) null ); } public String getModulePathAdjustment( MavenProject mavenProject ) throws IOException { return ""; } public Artifact getArtifact() { if ( artifact == null ) { ArtifactHandler ah = new DefaultArtifactHandlerStub( "jar", null ); VersionRange vr = VersionRange.createFromVersion( "1.0" ); Artifact art = new DefaultArtifact( "group", "artifact", vr, Artifact.SCOPE_COMPILE, "jar", null, ah, false ); setArtifact( art ); } return artifact; } public void setArtifact( Artifact artifact ) { this.artifact = artifact; } public Model getModel() { return model; } public MavenProject getParent() { return parent; } public void setParent( MavenProject mavenProject ) { this.parent = mavenProject; } public void setRemoteArtifactRepositories( List list ) { } public List getRemoteArtifactRepositories() { return Collections.singletonList( "" ); } public boolean hasParent() { if ( parent != null ) { return true; } else { return false; } } public File getFile() { return file; } public void setFile( File file ) { this.file = file; } public File getBasedir() { return new File( PlexusTestCase.getBasedir() ); } public void setDependencies( List list ) { dependencies = list; } public List getDependencies() { if ( dependencies == null ) { dependencies = Collections.EMPTY_LIST; } return dependencies; } public void setDependencyManagement(DependencyManagement depMgt) { this.dependencyManagement = depMgt; } public DependencyManagement getDependencyManagement() { if ( dependencyManagement == null ) { dependencyManagement = new DependencyManagement(); } return dependencyManagement; } public void addCompileSourceRoot( String string ) { if ( compileSourceRoots == null ) { compileSourceRoots = Collections.singletonList( string ); } else { compileSourceRoots.add( string ); } } public void addScriptSourceRoot( String string ) { if ( scriptSourceRoots == null ) { scriptSourceRoots = Collections.singletonList( string ); } else { scriptSourceRoots.add( string ); } } public void addTestCompileSourceRoot( String string ) { if ( testCompileSourceRoots == null ) { testCompileSourceRoots = Collections.singletonList( string ); } else { testCompileSourceRoots.add( string ); } } public List getCompileSourceRoots() { return compileSourceRoots; } public List getScriptSourceRoots() { return scriptSourceRoots; } public List getTestCompileSourceRoots() { return testCompileSourceRoots; } public List getCompileClasspathElements() throws DependencyResolutionRequiredException { return compileSourceRoots; } public void setCompileArtifacts( List compileArtifacts ) { this.compileArtifacts = compileArtifacts; } public List getCompileArtifacts() { return compileArtifacts; } public List getCompileDependencies() { return compileDependencies; } public List getTestClasspathElements() throws DependencyResolutionRequiredException { return testClasspathElements; } public List getTestArtifacts() { return testArtifacts; } public List getTestDependencies() { return testDependencies; } public List getRuntimeClasspathElements() throws DependencyResolutionRequiredException { return runtimeClasspathElements; } public List getRuntimeArtifacts() { return runtimeArtifacts; } public List getRuntimeDependencies() { return runtimeDependencies; } public List getSystemClasspathElements() throws DependencyResolutionRequiredException { return systemClasspathElements; } public List getSystemArtifacts() { return systemArtifacts; } public void setRuntimeClasspathElements( List runtimeClasspathElements ) { this.runtimeClasspathElements = runtimeClasspathElements; } public void setAttachedArtifacts( List attachedArtifacts ) { this.attachedArtifacts = attachedArtifacts; } public void setCompileSourceRoots( List compileSourceRoots ) { this.compileSourceRoots = compileSourceRoots; } public void setTestCompileSourceRoots( List testCompileSourceRoots ) { this.testCompileSourceRoots = testCompileSourceRoots; } public void setScriptSourceRoots( List scriptSourceRoots ) { this.scriptSourceRoots = scriptSourceRoots; } public void setArtifactMap( Map artifactMap ) { // this.artifactMap = artifactMap; } public void setPluginArtifactMap( Map pluginArtifactMap ) { // this.pluginArtifactMap = pluginArtifactMap; } public void setReportArtifactMap( Map reportArtifactMap ) { // this.reportArtifactMap = reportArtifactMap; } public void setExtensionArtifactMap( Map extensionArtifactMap ) { // this.extensionArtifactMap = extensionArtifactMap; } public void setProjectReferences( Map projectReferences ) { // this.projectReferences = projectReferences; } public void setBuildOverlay( Build buildOverlay ) { // this.buildOverlay = buildOverlay; } public void setCompileDependencies( List compileDependencies ) { this.compileDependencies = compileDependencies; } public void setSystemDependencies( List systemDependencies ) { this.systemDependencies = systemDependencies; } public void setTestClasspathElements( List testClasspathElements ) { this.testClasspathElements = testClasspathElements; } public void setTestDependencies( List testDependencies ) { this.testDependencies = testDependencies; } public void setSystemClasspathElements( List systemClasspathElements ) { this.systemClasspathElements = systemClasspathElements; } public void setSystemArtifacts( List systemArtifacts ) { this.systemArtifacts = systemArtifacts; } public void setTestArtifacts( List testArtifacts ) { this.testArtifacts = testArtifacts; } public void setRuntimeArtifacts( List runtimeArtifacts ) { this.runtimeArtifacts = runtimeArtifacts; } public void setRuntimeDependencies( List runtimeDependencies ) { this.runtimeDependencies = runtimeDependencies; } public void setModel( Model model ) { this.model = model; } public List getSystemDependencies() { return systemDependencies; } public void setModelVersion( String string ) { this.modelVersion = string; } public String getModelVersion() { return modelVersion; } public String getId() { return ""; } public void setGroupId( String string ) { this.groupId = string; } public String getGroupId() { return groupId; } public void setArtifactId( String string ) { this.artifactId = string; } public String getArtifactId() { return artifactId; } public void setName( String string ) { this.name = string; } public String getName() { return name; } public void setVersion( String string ) { this.version = string; } public String getVersion() { return version; } public String getPackaging() { return packaging; } public void setPackaging( String string ) { this.packaging = string; } public void setInceptionYear( String string ) { this.inceptionYear = string; } public String getInceptionYear() { return inceptionYear; } public void setUrl( String string ) { this.url = string; } public String getUrl() { return url; } public Prerequisites getPrerequisites() { return null; } public void setIssueManagement( IssueManagement issueManagement ) { } public CiManagement getCiManagement() { return null; } public void setCiManagement( CiManagement ciManagement ) { } public IssueManagement getIssueManagement() { return null; } public void setDistributionManagement( DistributionManagement distributionManagement ) { } public DistributionManagement getDistributionManagement() { return null; } public void setDescription( String string ) { this.description = string; } public String getDescription() { return description; } public void setOrganization( Organization organization ) { } public Organization getOrganization() { return null; } public void setScm( Scm scm ) { } public Scm getScm() { return null; } public void setMailingLists( List list ) { } public List getMailingLists() { return Collections.singletonList( "" ); } public void addMailingList( MailingList mailingList ) { } public void setDevelopers( List list ) { } public List getDevelopers() { return Collections.singletonList( "" ); } public void addDeveloper( Developer developer ) { } public void setContributors( List list ) { } public List getContributors() { return Collections.singletonList( "" ); } public void addContributor( Contributor contributor ) { } public void setBuild( Build build ) { } public Build getBuild() { return null; } public List getResources() { return Collections.singletonList( "" ); } public List getTestResources() { return Collections.singletonList( "" ); } public void addResource( Resource resource ) { } public void addTestResource( Resource resource ) { } public void setReporting( Reporting reporting ) { } public Reporting getReporting() { return null; } public void setLicenses( List list ) { } public List getLicenses() { return Collections.singletonList( "" ); } public void addLicense( License license ) { } public void setArtifacts( Set set ) { this.artifacts = set; } public Set getArtifacts() { if ( artifacts == null ) { return Collections.EMPTY_SET; } else { return artifacts; } } public Map getArtifactMap() { return Collections.singletonMap( "", "" ); } public void setPluginArtifacts( Set set ) { } public Set getPluginArtifacts() { return Collections.singleton( "" ); } public Map getPluginArtifactMap() { return Collections.singletonMap( "", "" ); } public void setReportArtifacts( Set set ) { } public Set getReportArtifacts() { return Collections.singleton( "" ); } public Map getReportArtifactMap() { return Collections.singletonMap( "", "" ); } public void setExtensionArtifacts( Set set ) { } public Set getExtensionArtifacts() { return Collections.singleton( "" ); } public Map getExtensionArtifactMap() { return Collections.singletonMap( "", "" ); } public void setParentArtifact( Artifact artifact ) { } public Artifact getParentArtifact() { return null; } public List getRepositories() { return Collections.singletonList( "" ); } public List getReportPlugins() { return Collections.singletonList( "" ); } public List getBuildPlugins() { return Collections.singletonList( "" ); } public List getModules() { return Collections.singletonList( "" ); } public PluginManagement getPluginManagement() { return null; } public void addPlugin( Plugin plugin ) { } public void injectPluginManagementInfo( Plugin plugin ) { } public List getCollectedProjects() { return collectedProjects; } public void setCollectedProjects( List list ) { this.collectedProjects = list; } public void setPluginArtifactRepositories( List list ) { this.pluginArtifactRepositories = list; } public List getPluginArtifactRepositories() { return pluginArtifactRepositories; } public ArtifactRepository getDistributionManagementArtifactRepository() { return null; } public List getPluginRepositories() { return Collections.singletonList( "" ); } public void setActiveProfiles( List list ) { activeProfiles = list; } public List getActiveProfiles() { return activeProfiles; } public void addAttachedArtifact( Artifact theArtifact ) { if ( attachedArtifacts == null ) { this.attachedArtifacts = Collections.singletonList( theArtifact ); } else { attachedArtifacts.add( theArtifact ); } } public List getAttachedArtifacts() { return attachedArtifacts; } public Xpp3Dom getGoalConfiguration( String string, String string1, String string2, String string3 ) { return null; } public Xpp3Dom getReportConfiguration( String string, String string1, String string2 ) { return null; } public MavenProject getExecutionProject() { return null; } public void setExecutionProject( MavenProject mavenProject ) { } public void writeModel( Writer writer ) throws IOException { } public void writeOriginalModel( Writer writer ) throws IOException { } public Set getDependencyArtifacts() { return dependencyArtifacts; } public void setDependencyArtifacts( Set set ) { this.dependencyArtifacts = set; } public void setReleaseArtifactRepository( ArtifactRepository artifactRepository ) { // this.releaseArtifactRepository = artifactRepository; } public void setSnapshotArtifactRepository( ArtifactRepository artifactRepository ) { // this.snapshotArtifactRepository = artifactRepository; } public void setOriginalModel( Model model ) { this.originalModel = model; } public Model getOriginalModel() { return originalModel; } public List getBuildExtensions() { return Collections.singletonList( "" ); } public Set createArtifacts( ArtifactFactory artifactFactory, String string, ArtifactFilter artifactFilter ) throws InvalidDependencyVersionException { return Collections.EMPTY_SET; } public void addProjectReference( MavenProject mavenProject ) { } public void attachArtifact( String string, String string1, File theFile ) { } public Properties getProperties() { return new Properties(); } public List getFilters() { return Collections.singletonList( "" ); } public Map getProjectReferences() { return Collections.singletonMap( "", "" ); } public boolean isExecutionRoot() { return executionRoot; } public void setExecutionRoot( boolean b ) { this.executionRoot = b; } public String getDefaultGoal() { return defaultGoal; } public Artifact replaceWithActiveArtifact( Artifact theArtifact ) { return null; } } antlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/DefaultArtifactHandlerStub.java0000664000175000017500000000304210773161441032770 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.stubs; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.maven.artifact.handler.DefaultArtifactHandler; /** * @author Vincent Siveton * @version $Id: DefaultArtifactHandlerStub.java 6588 2008-03-28 12:22:57Z bentmann $ */ public class DefaultArtifactHandlerStub extends DefaultArtifactHandler { private String language; /** * @see org.apache.maven.artifact.handler.ArtifactHandler#getLanguage() */ public String getLanguage() { if ( language == null ) { language = "java"; } return language; } /** * @param language */ public void setLanguage( String language ) { this.language = language; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/JavaGrammarTestMavenProjectStub.javaantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/JavaGrammarTestMavenProjectStub.j0000664000175000017500000000343010773161441033307 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.stubs; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.FileReader; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.testing.stubs.MavenProjectStub; /** * @author Vincent Siveton * @version $Id: JavaGrammarTestMavenProjectStub.java 6588 2008-03-28 12:22:57Z bentmann $ */ public class JavaGrammarTestMavenProjectStub extends MavenProjectStub { /** * Default */ public JavaGrammarTestMavenProjectStub() { MavenXpp3Reader pomReader = new MavenXpp3Reader(); Model model = null; try { model = pomReader.read( new FileReader( new File( getBasedir() + "/src/test/resources/unit/java-grammar-test/java-grammar-test-plugin-config.xml" ) ) ); setModel( model ); } catch ( Exception e ) { throw new RuntimeException( e ); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/DependencyArtifactStubFactory.javaantlr-maven-plugin-2.2/src/test/java/org/codehaus/mojo/antlr/stubs/DependencyArtifactStubFactory.jav0000664000175000017500000000232710773161441033360 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.stubs; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import org.apache.maven.plugin.testing.ArtifactStubFactory; /** * DependencyArtifactStubFactory implementation * * @author Steve Ebersole */ public class DependencyArtifactStubFactory extends ArtifactStubFactory { public DependencyArtifactStubFactory( File theWorkingDir, boolean theCreateFiles ) { super( theWorkingDir, theCreateFiles ); } }antlr-maven-plugin-2.2/src/it/0000775000175000017500000000000012165015352015632 5ustar ebourgebourgantlr-maven-plugin-2.2/src/it/java-grammar-report-test/0000775000175000017500000000000012165015352022465 5ustar ebourgebourgantlr-maven-plugin-2.2/src/it/java-grammar-report-test/pom.xml0000664000175000017500000000602510773161441024011 0ustar ebourgebourg 4.0.0 org.codehaus.mojo.antlr java-grammar-report-test jar 1.0-SNAPSHOT 2006 Maven Antlr Plugin Java-grammar Report IT Test http://mojo.codehaus.org antlr antlr 2.7.7 org.codehaus.mojo antlr-maven-plugin 2.0 java15.g it-local-repo file://${basedir}/../../../target/local-repo apache.snapshots Maven Snapshots http://people.apache.org/maven-snapshot-repository false true apache.snapshots Maven Plugin Snapshots http://people.apache.org/maven-snapshot-repository false false org.apache.maven.plugins maven-site-plugin 2.0-beta-5 antlr-maven-plugin-2.2/src/it/java-grammar-report-test/verify.bsh0000664000175000017500000000250110773161441024471 0ustar ebourgebourgimport java.io.BufferedReader; import java.io.File; import java.io.IOException; import org.codehaus.plexus.util.IOUtil; File outputDir = new File( basedir, "target/site/antlr" ); if ( !outputDir.isDirectory() || !outputDir.exists() ) { System.err.println( "The file '" + outputDir.getAbsolutePath() + "' is not a directory or doesn't exist." ); return false; } File index = new File( outputDir, "index.html" ); if ( !index.isFile() || !index.exists() ) { System.err.println( "The file '" + index.getAbsolutePath() + "' is not a file or doesn't exist." ); return false; } String indexContent = ""; try { BufferedReader in = new BufferedReader( new FileReader( index ) ); indexContent = IOUtil.toString( in ); } catch( IOException e ) { System.err.println( "IOException: " + e.getMessage() ); return false; } if ( indexContent.indexOf( "JavaRecognizer" ) == -1 ) { System.err.println( "The file '" + index.getAbsolutePath() + "' should have JavaRecognizer" ); return false; } File javaRecognizer = new File( outputDir, "JavaRecognizer.html" ); if ( !javaRecognizer.isFile() || !javaRecognizer.exists() ) { System.err.println( "The file '" + javaRecognizer.getAbsolutePath() + "' is not a file or doesn't exist." ); return false; } return true; antlr-maven-plugin-2.2/src/it/java-grammar-report-test/src/0000775000175000017500000000000012165015352023254 5ustar ebourgebourgantlr-maven-plugin-2.2/src/it/java-grammar-report-test/src/main/0000775000175000017500000000000012165015352024200 5ustar ebourgebourgantlr-maven-plugin-2.2/src/it/java-grammar-report-test/src/main/antlr/0000775000175000017500000000000012165015352025320 5ustar ebourgebourgantlr-maven-plugin-2.2/src/it/java-grammar-report-test/src/main/antlr/java15.g0000664000175000017500000014316510647361554026604 0ustar ebourgebourg/** Java 1.5 Recognizer /** Java 1.5 Recognizer * * Run 'java Main [-showtree] directory-full-of-java-files' * * [The -showtree option pops up a Swing frame that shows * the AST constructed from the parser.] * * Run 'java Main ' * * Contributing authors: * John Mitchell johnm@non.net * Terence Parr parrt@magelang.com * John Lilley jlilley@empathy.com * Scott Stanchfield thetick@magelang.com * Markus Mohnen mohnen@informatik.rwth-aachen.de * Peter Williams pete.williams@sun.com * Allan Jacobs Allan.Jacobs@eng.sun.com * Steve Messick messick@redhills.com * John Pybus john@pybus.org * * Version 1.00 December 9, 1997 -- initial release * Version 1.01 December 10, 1997 * fixed bug in octal def (0..7 not 0..8) * Version 1.10 August 1998 (parrt) * added tree construction * fixed definition of WS,comments for mac,pc,unix newlines * added unary plus * Version 1.11 (Nov 20, 1998) * Added "shutup" option to turn off last ambig warning. * Fixed inner class def to allow named class defs as statements * synchronized requires compound not simple statement * add [] after builtInType DOT class in primaryExpression * "const" is reserved but not valid..removed from modifiers * Version 1.12 (Feb 2, 1999) * Changed LITERAL_xxx to xxx in tree grammar. * Updated java.g to use tokens {...} now for 2.6.0 (new feature). * * Version 1.13 (Apr 23, 1999) * Didn't have (stat)? for else clause in tree parser. * Didn't gen ASTs for interface extends. Updated tree parser too. * Updated to 2.6.0. * Version 1.14 (Jun 20, 1999) * Allowed final/abstract on local classes. * Removed local interfaces from methods * Put instanceof precedence where it belongs...in relationalExpr * It also had expr not type as arg; fixed it. * Missing ! on SEMI in classBlock * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus). * fixed: didn't like Object[].class in parser or tree parser * Version 1.15 (Jun 26, 1999) * Screwed up rule with instanceof in it. :( Fixed. * Tree parser didn't like (expr).something; fixed. * Allowed multiple inheritance in tree grammar. oops. * Version 1.16 (August 22, 1999) * Extending an interface built a wacky tree: had extra EXTENDS. * Tree grammar didn't allow multiple superinterfaces. * Tree grammar didn't allow empty var initializer: {} * Version 1.17 (October 12, 1999) * ESC lexer rule allowed 399 max not 377 max. * java.tree.g didn't handle the expression of synchronized * statements. * Version 1.18 (August 12, 2001) * Terence updated to Java 2 Version 1.3 by * observing/combining work of Allan Jacobs and Steve * Messick. Handles 1.3 src. Summary: * o primary didn't include boolean.class kind of thing * o constructor calls parsed explicitly now: * see explicitConstructorInvocation * o add strictfp modifier * o missing objBlock after new expression in tree grammar * o merged local class definition alternatives, moved after declaration * o fixed problem with ClassName.super.field * o reordered some alternatives to make things more efficient * o long and double constants were not differentiated from int/float * o whitespace rule was inefficient: matched only one char * o add an examples directory with some nasty 1.3 cases * o made Main.java use buffered IO and a Reader for Unicode support * o supports UNICODE? * Using Unicode charVocabulay makes code file big, but only * in the bitsets at the end. I need to make ANTLR generate * unicode bitsets more efficiently. * Version 1.19 (April 25, 2002) * Terence added in nice fixes by John Pybus concerning floating * constants and problems with super() calls. John did a nice * reorg of the primary/postfix expression stuff to read better * and makes f.g.super() parse properly (it was METHOD_CALL not * a SUPER_CTOR_CALL). Also: * * o "finally" clause was a root...made it a child of "try" * o Added stuff for asserts too for Java 1.4, but *commented out* * as it is not backward compatible. * * Version 1.20 (October 27, 2002) * * Terence ended up reorging John Pybus' stuff to * remove some nondeterminisms and some syntactic predicates. * Note that the grammar is stricter now; e.g., this(...) must * be the first statement. * * Trinary ?: operator wasn't working as array name: * (isBig ? bigDigits : digits)[i]; * * Checked parser/tree parser on source for * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4, * and the 110k-line jGuru server source. * * Version 1.21 (October 17, 2003) * Fixed lots of problems including: * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g * He found a problem/fix with floating point that start with 0 * Ray also fixed problem that (int.class) was not recognized. * Thorsten van Ellen noticed that \n are allowed incorrectly in strings. * TJP fixed CHAR_LITERAL analogously. * * Version 1.21.2 (March, 2003) * Changes by Matt Quail to support generics (as per JDK1.5/JSR14) * Notes: * o We only allow the "extends" keyword and not the "implements" * keyword, since thats what JSR14 seems to imply. * o Thanks to Monty Zukowski for his help on the antlr-interest * mail list. * o Thanks to Alan Eliasen for testing the grammar over his * Fink source base * * Version 1.22 (July, 2004) * Changes by Michael Studman to support Java 1.5 language extensions * Notes: * o Added support for annotations types * o Finished off Matt Quail's generics enhancements to support bound type arguments * o Added support for new for statement syntax * o Added support for static import syntax * o Added support for enum types * o Tested against JDK 1.5 source base and source base of jdigraph project * o Thanks to Matt Quail for doing the hard part by doing most of the generics work * * Version 1.22.1 (July 28, 2004) * Bug/omission fixes for Java 1.5 language support * o Fixed tree structure bug with classOrInterface - thanks to Pieter Vangorpto for * spotting this * o Fixed bug where incorrect handling of SR and BSR tokens would cause type * parameters to be recognised as type arguments. * o Enabled type parameters on constructors, annotations on enum constants * and package definitions * o Fixed problems when parsing if ((char.class.equals(c))) {} - solution by Matt Quail at Cenqua * * Version 1.22.2 (July 28, 2004) * Slight refactoring of Java 1.5 language support * o Refactored for/"foreach" productions so that original literal "for" literal * is still used but the for sub-clauses vary by token type * o Fixed bug where type parameter was not included in generic constructor's branch of AST * * Version 1.22.3 (August 26, 2004) * Bug fixes as identified by Michael Stahl; clean up of tabs/spaces * and other refactorings * o Fixed typeParameters omission in identPrimary and newStatement * o Replaced GT reconcilliation code with simple semantic predicate * o Adapted enum/assert keyword checking support from Michael Stahl's java15 grammar * o Refactored typeDefinition production and field productions to reduce duplication * * Version 1.22.4 (October 21, 2004) * Small bux fixes * o Added typeArguments to explicitConstructorInvocation, e.g. new MyParameterised() * o Added typeArguments to postfixExpression productions for anonymous inner class super * constructor invocation, e.g. new Outer().super() * o Fixed bug in array declarations identified by Geoff Roy * * Version 1.22.5 (January 03, 2005) * Small change to tree structure * o Flattened classOrInterfaceType tree so IDENT no longer has children. TYPE_ARGUMENTS are now * always siblings of IDENT rather than children. Fully.qualified.names trees now * look a little less clean when TYPE_ARGUMENTS are present though. * * This grammar is in the PUBLIC DOMAIN */ 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; VARIABLE_PARAMETER_DEF; STATIC_IMPORT; ENUM_DEF; ENUM_CONSTANT_DEF; FOR_EACH_CLAUSE; ANNOTATION_DEF; ANNOTATIONS; ANNOTATION; ANNOTATION_MEMBER_VALUE_PAIR; ANNOTATION_FIELD_DEF; ANNOTATION_ARRAY_INIT; TYPE_ARGUMENTS; TYPE_ARGUMENT; TYPE_PARAMETERS; TYPE_PARAMETER; WILDCARD_TYPE; TYPE_UPPER_BOUNDS; TYPE_LOWER_BOUNDS; } { /** * Counts the number of LT seen in the typeArguments production. * It is used in semantic predicates to ensure we have seen * enough closing '>' characters; which actually may have been * either GT, SR or BSR tokens. */ private int ltCounter = 0; } // Compilation Unit: In Java, this is a single file. This is the start // rule for this parser compilationUnit : // A compilation unit starts with an optional package definition ( (annotations "package")=> 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! ; // Package statement: optional annotations followed by "package" then the package identifier. packageDefinition options {defaultErrorHandler = true;} // let ANTLR handle errors : annotations p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI! ; // Import statement: import followed by a package or class name importDefinition options {defaultErrorHandler = true;} { boolean isStatic = false; } : i:"import"^ {#i.setType(IMPORT);} ( "static"! {#i.setType(STATIC_IMPORT);} )? identifierStar SEMI! ; // A type definition is either a class, interface, enum or annotation with possible additional semis. typeDefinition options {defaultErrorHandler = true;} : m:modifiers! typeDefinitionInternal[#m] | SEMI! ; // Protected type definitions production for reuse in other productions protected typeDefinitionInternal[AST mods] : classDefinition[#mods] // inner class | interfaceDefinition[#mods] // inner interface | enumDefinition[#mods] // inner enum | annotationDefinition[#mods] // inner annotation ; // 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 either: // - possible brackets afterwards // (which would make it an array type). // - generic type arguments after classTypeSpec[boolean addImagNode] : classOrInterfaceType[false] (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )* { if ( addImagNode ) { #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec); } } ; // A non-built in type name, with possible type parameters classOrInterfaceType[boolean addImagNode] : IDENT (typeArguments)? (options{greedy=true;}: // match as many as possible DOT^ IDENT (typeArguments)? )* { if ( addImagNode ) { #classOrInterfaceType = #(#[TYPE,"TYPE"], #classOrInterfaceType); } } ; // A specialised form of typeSpec where built in types must be arrays typeArgumentSpec : classTypeSpec[true] | builtInTypeArraySpec[true] ; // A generic type argument is a class type, a possibly bounded wildcard type or a built-in type array typeArgument : ( typeArgumentSpec | wildcardType ) {#typeArgument = #(#[TYPE_ARGUMENT,"TYPE_ARGUMENT"], #typeArgument);} ; // Wildcard type indicating all types (with possible constraint) wildcardType : q:QUESTION^ {#q.setType(WILDCARD_TYPE);} (("extends" | "super")=> typeArgumentBounds)? ; // Type arguments to a class or interface type typeArguments {int currentLtLevel = 0;} : {currentLtLevel = ltCounter;} LT! {ltCounter++;} typeArgument (options{greedy=true;}: // match as many as possible {inputState.guessing !=0 || ltCounter == currentLtLevel + 1}? COMMA! typeArgument )* ( // turn warning off since Antlr generates the right code, // plus we have our semantic predicate below options{generateAmbigWarnings=false;}: typeArgumentsOrParametersEnd )? // make sure we have gobbled up enough '>' characters // if we are at the "top level" of nested typeArgument productions {(currentLtLevel != 0) || ltCounter == currentLtLevel}? {#typeArguments = #(#[TYPE_ARGUMENTS, "TYPE_ARGUMENTS"], #typeArguments);} ; // this gobbles up *some* amount of '>' characters, and counts how many // it gobbled. protected typeArgumentsOrParametersEnd : GT! {ltCounter-=1;} | SR! {ltCounter-=2;} | BSR! {ltCounter-=3;} ; // Restriction on wildcard types based on super class or derrived class typeArgumentBounds {boolean isUpperBounds = false;} : ( "extends"! {isUpperBounds=true;} | "super"! ) classOrInterfaceType[false] { if (isUpperBounds) { #typeArgumentBounds = #(#[TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS"], #typeArgumentBounds); } else { #typeArgumentBounds = #(#[TYPE_LOWER_BOUNDS,"TYPE_LOWER_BOUNDS"], #typeArgumentBounds); } } ; // A builtin type array specification is a builtin type with brackets afterwards builtInTypeArraySpec[boolean addImagNode] : builtInType (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )+ { if ( addImagNode ) { #builtInTypeArraySpec = #(#[TYPE,"TYPE"], #builtInTypeArraySpec); } } ; // A builtin type specification is a builtin type with possible brackets // afterwards (which would make it an array type). builtInTypeSpec[boolean addImagNode] : builtInType (options{greedy=true;}: // match as many as possible lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK! )* { if ( addImagNode ) { #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec); } } ; // A type name. which is either a (possibly qualified and parameterized) // class name or a primitive (builtin) type type : classOrInterfaceType[false] | 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 IDENTS identifier : 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 desires modifiers : ( //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 = #([MODIFIERS, "MODIFIERS"], #modifiers);} ; // modifiers for Java classes, interfaces, class/instance vars and methods modifier : "private" | "public" | "protected" | "static" | "transient" | "final" | "abstract" | "native" | "threadsafe" | "synchronized" | "volatile" | "strictfp" ; annotation! : AT! i:identifier ( LPAREN! ( args:annotationArguments )? RPAREN! )? {#annotation = #(#[ANNOTATION,"ANNOTATION"], i, args);} ; annotations : (annotation)* {#annotations = #([ANNOTATIONS, "ANNOTATIONS"], #annotations);} ; annotationArguments : annotationMemberValueInitializer | anntotationMemberValuePairs ; anntotationMemberValuePairs : annotationMemberValuePair ( COMMA! annotationMemberValuePair )* ; annotationMemberValuePair! : i:IDENT ASSIGN! v:annotationMemberValueInitializer {#annotationMemberValuePair = #(#[ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR"], 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! : ( "extends" c:classOrInterfaceType[false] )? {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],c);} ; // Definition of a Java class classDefinition![AST modifiers] : "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 = #(#[CLASS_DEF,"CLASS_DEF"], modifiers,IDENT,tp,sc,ic,cb);} ; // Definition of a Java Interface interfaceDefinition![AST modifiers] : "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 = #(#[INTERFACE_DEF,"INTERFACE_DEF"], modifiers,IDENT,tp,ie,ib);} ; enumDefinition![AST modifiers] : "enum" IDENT // it might implement some interfaces... ic:implementsClause // now parse the body of the enum eb:enumBlock {#enumDefinition = #(#[ENUM_DEF,"ENUM_DEF"], modifiers,IDENT,ic,eb);} ; annotationDefinition![AST modifiers] : AT "interface" IDENT // now parse the body of the annotation ab:annotationBlock {#annotationDefinition = #(#[ANNOTATION_DEF,"ANNOTATION_DEF"], modifiers,IDENT,ab);} ; typeParameters {int currentLtLevel = 0;} : {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 = #(#[TYPE_PARAMETERS, "TYPE_PARAMETERS"], #typeParameters);} ; typeParameter : // I'm pretty sure Antlr generates the right thing here: (id:IDENT) ( options{generateAmbigWarnings=false;}: typeParameterBounds )? {#typeParameter = #(#[TYPE_PARAMETER,"TYPE_PARAMETER"], #typeParameter);} ; typeParameterBounds : "extends"! classOrInterfaceType[false] (BAND! classOrInterfaceType[false])* {#typeParameterBounds = #(#[TYPE_UPPER_BOUNDS,"TYPE_UPPER_BOUNDS"], #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 class enumBlock : LCURLY! ( enumConstant ( options{greedy=true;}: COMMA! enumConstant )* ( COMMA! )? )? ( SEMI! ( classField | SEMI! )* )? RCURLY! {#enumBlock = #([OBJBLOCK, "OBJBLOCK"], #enumBlock);} ; // An annotation field annotationField! : 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 = #(#[ANNOTATION_FIELD_DEF,"ANNOTATION_FIELD_DEF"], mods, #(#[TYPE,"TYPE"],rt), i,amvi );} | v:variableDefinitions[#mods,#t] SEMI // variable {#annotationField = #v;} ) ) ; //An enum constant may have optional parameters and may have a //a class body enumConstant! : 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 constant enumConstantBlock : 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 initializer enumConstantField! : 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#enumConstantField = #v;} ) ) // "{ ... }" instance initializer | s4:compoundStatement {#enumConstantField = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ; // An interface can extend several other interfaces... interfaceExtends : ( e:"extends"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"], #interfaceExtends);} ; // A class can implement several interfaces... implementsClause : ( i:"implements"! classOrInterfaceType[false] ( COMMA! classOrInterfaceType[false] )* )? {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"], #implementsClause);} ; // Now the various things that can be defined inside a class classField! : // method, constructor, or variable declaration mods:modifiers ( td:typeDefinitionInternal[#mods] {#classField = #td;} | (tp:typeParameters)? ( h:ctorHead s:constructorBody // constructor {#classField = #(#[CTOR_DEF,"CTOR_DEF"], 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],rt), IDENT, param, tc, s2);} | v:variableDefinitions[#mods,#t] SEMI {#classField = #v;} ) ) ) // "static { ... }" class initializer | "static" s3:compoundStatement {#classField = #(#[STATIC_INIT,"STATIC_INIT"], s3);} // "{ ... }" instance initializer | s4:compoundStatement {#classField = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);} ; // Now the various things that can be defined inside a interface interfaceField! : // 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 = #(#[METHOD_DEF,"METHOD_DEF"], mods, tp, #(#[TYPE,"TYPE"],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().dupList(t)] //dupList as this also copies siblings (like TYPE_ARGUMENTS) ( COMMA! variableDeclarator[getASTFactory().dupTree(mods), getASTFactory().dupList(t)] //dupList as this also copies siblings (like TYPE_ARGUMENTS) )* ; /** 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 throw throwsClause : "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 parameter parameterDeclarationList // 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 = #(#[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);} ; variableLengthParameterDeclaration! : pm:parameterModifier t:typeSpec[false] TRIPLE_DOT! id:IDENT pd:declaratorBrackets[#t] {#variableLengthParameterDeclaration = #(#[VARIABLE_PARAMETER_DEF,"VARIABLE_PARAMETER_DEF"], pm, #([TYPE,"TYPE"],pd), id);} ; parameterModifier //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 = #(#[MODIFIERS,"MODIFIERS"], #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 definitions compoundStatement : 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 | "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 : p:parameterDeclaration COLON! expression {#forEachClause = #(#[FOR_EACH_CLAUSE,"FOR_EACH_CLAUSE"], #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 : (statement)* {#caseSList = #(#[SLIST,"SLIST"],#caseSList);} ; // The initializer for a for loop forInit // 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 block tryBlock : "try"^ compoundStatement (handler)* ( finallyClause )? ; finallyClause : "finally"^ compoundStatement ; // an exception handler handler : "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 expressions expression : 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^ 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/dec postfixExpression : 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 expression primaryExpression : 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 // 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... // this will also produce an ANTLR warning! // Unfortunately a syntactic predicate can only select one of // multiple alternatives on the same level, not break out of // an enclosing loop, which is why this ugly hack (a fake // empty alternative with always-false semantic predicate) // is necessary. )* ( options { // ARRAY_DECLARATOR here conflicts with INDEX_OP in // postfixExpression on LBRACK RBRACK. // We want to match [] here, so greedy. This overcomes // limitation of linear approximate lookahead. greedy=true; } : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} // if the input is valid, only the last IDENT may // have preceding typeArguments... rather hacky, this is... {if (#ta2 != null) astFactory.addASTChild(currentAST, #ta2);} {if (#ta2 == null) astFactory.addASTChild(currentAST, #ta1);} argList RPAREN! ) | ( options {greedy=true;} : lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+ )? ; /** 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"^ (typeArguments)? 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 | NUM_LONG | NUM_DOUBLE ; //---------------------------------------------------------------------------- // The Java scanner //---------------------------------------------------------------------------- class JavaLexer extends Lexer; options { exportVocab=Java; // call the vocabulary "Java" testLiterals=false; // don't automatically test for literals k=4; // four characters of lookahead charVocabulary='\u0003'..'\uFFFF'; // without inlining some bitset tests, couldn't do unicode; // I need to make ANTLR generate smaller bitsets; see // bottom of JavaLexer.java codeGenBitsetTestThreshold=20; } { /** flag for enabling the "assert" keyword */ private boolean assertEnabled = true; /** flag for enabling the "enum" keyword */ private boolean enumEnabled = true; /** Enable the "assert" keyword */ public void enableAssert(boolean shouldEnable) { assertEnabled = shouldEnable; } /** Query the "assert" keyword state */ public boolean isAssertEnabled() { return assertEnabled; } /** Enable the "enum" keyword */ public void enableEnum(boolean shouldEnable) { enumEnabled = shouldEnable; } /** Query the "enum" keyword state */ public boolean isEnumEnabled() { return enumEnabled; } } // OPERATORS QUESTION : '?' ; LPAREN : '(' ; RPAREN : ')' ; LBRACK : '[' ; RBRACK : ']' ; LCURLY : '{' ; RCURLY : '}' ; COLON : ':' ; COMMA : ',' ; //DOT : '.' ; ASSIGN : '=' ; EQUAL : "==" ; LNOT : '!' ; BNOT : '~' ; NOT_EQUAL : "!=" ; DIV : '/' ; DIV_ASSIGN : "/=" ; PLUS : '+' ; PLUS_ASSIGN : "+=" ; INC : "++" ; MINUS : '-' ; MINUS_ASSIGN : "-=" ; DEC : "--" ; STAR : '*' ; STAR_ASSIGN : "*=" ; MOD : '%' ; MOD_ASSIGN : "%=" ; SR : ">>" ; SR_ASSIGN : ">>=" ; BSR : ">>>" ; BSR_ASSIGN : ">>>=" ; GE : ">=" ; GT : ">" ; SL : "<<" ; SL_ASSIGN : "<<=" ; LE : "<=" ; LT : '<' ; BXOR : '^' ; BXOR_ASSIGN : "^=" ; BOR : '|' ; BOR_ASSIGN : "|=" ; LOR : "||" ; BAND : '&' ; BAND_ASSIGN : "&=" ; LAND : "&&" ; SEMI : ';' ; // Whitespace -- ignored WS : ( ' ' | '\t' | '\f' // handle newlines | ( options {generateAmbigWarnings=false;} : "\r\n" // Evil DOS | '\r' // Macintosh | '\n' // Unix (the right way) ) { newline(); } )+ { _ttype = Token.SKIP; } ; // Single-line comments SL_COMMENT : "//" (~('\n'|'\r'))* ('\n'|'\r'('\n')?) {$setType(Token.SKIP); newline();} ; // multiple-line comments ML_COMMENT : "/*" ( /* '\r' '\n' can be matched in one alternative or by matching '\r' in one iteration and '\n' in another. I am trying to handle any flavor of newline that comes in, but the language that allows both "\r\n" and "\r" and "\n" to all be valid newline is ambiguous. Consequently, the resulting grammar must be ambiguous. I'm shutting this warning off. */ options { generateAmbigWarnings=false; } : { LA(2)!='/' }? '*' | '\r' '\n' {newline();} | '\r' {newline();} | '\n' {newline();} | ~('*'|'\n'|'\r') )* "*/" {$setType(Token.SKIP);} ; // character literals CHAR_LITERAL : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\'' ; // string literals STRING_LITERAL : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"' ; // escape sequence -- note that this is protected; it can only be called // from another lexer rule -- it will not ever directly return a token to // the parser // There are various ambiguities hushed in this rule. The optional // '0'...'9' digit matches should be matched here rather than letting // them go back to STRING_LITERAL to be matched. ANTLR does the // right thing by matching immediately; hence, it's ok to shut off // the FOLLOW ambig warnings. protected ESC : '\\' ( 'n' | 'r' | 't' | 'b' | 'f' | '"' | '\'' | '\\' | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT | '0'..'3' ( options { warnWhenFollowAmbig = false; } : '0'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? )? | '4'..'7' ( options { warnWhenFollowAmbig = false; } : '0'..'7' )? ) ; // hexadecimal digit (again, note it's protected!) protected HEX_DIGIT : ('0'..'9'|'A'..'F'|'a'..'f') ; // a dummy rule to force vocabulary to be all characters (except special // ones that ANTLR uses internally (0 to 2) protected VOCAB : '\3'..'\377' ; // an identifier. Note that testLiterals is set to true! This means // that after we match the rule, we look in the literals table to see // if it's a literal or really an identifer IDENT options {testLiterals=true;} : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* { // check if "assert" keyword is enabled if (assertEnabled && "assert".equals($getText)) { $setType(LITERAL_assert); // set token type for the rule in the parser } // check if "enum" keyword is enabled if (enumEnabled && "enum".equals($getText)) { $setType(LITERAL_enum); // set token type for the rule in the parser } } ; // a numeric literal NUM_INT {boolean isDecimal=false; Token t=null;} : '.' {_ttype = DOT;} ( (('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})? { if (t != null && t.getText().toUpperCase().indexOf('F')>=0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } }) | // JDK 1.5 token for variable length arguments (".." {_ttype = TRIPLE_DOT;}) )? | ( '0' {isDecimal = true;} // special case for just '0' ( ('x'|'X') ( // hex // the 'e'|'E' and float suffix stuff look // like hex digits, hence the (...)+ doesn't // know when to stop: ambig. ANTLR resolves // it correctly by matching immediately. It // is therefor ok to hush warning. options { warnWhenFollowAmbig=false; } : HEX_DIGIT )+ | //float or double with leading zero (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+ | ('0'..'7')+ // octal )? | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal ) ( ('l'|'L') { _ttype = NUM_LONG; } // only check to see if it's a float if looks like decimal so far | {isDecimal}? ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})? | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})? | f4:FLOAT_SUFFIX {t=f4;} ) { if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) { _ttype = NUM_FLOAT; } else { _ttype = NUM_DOUBLE; // assume double } } )? ; // JDK 1.5 token for annotations and their declarations AT : '@' ; // a couple protected methods to assist in matching floating point numbers protected EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; protected FLOAT_SUFFIX : 'f'|'F'|'d'|'D' ;antlr-maven-plugin-2.2/src/changes/0000775000175000017500000000000012165015352016626 5ustar ebourgebourgantlr-maven-plugin-2.2/src/changes/changes.xml0000664000175000017500000000177411470604017020771 0ustar ebourgebourg Antlr Maven Plugin Changes Report Paul Gier ANTLR plugin does not track dependencies based on importVocab/exportVocab options ANTLR plugin does not reorder grammars connected by importVocab/exportVocab dependencies Impossible to utilize dependent grammars (import/export vocabs) using different packages antlr-maven-plugin-2.2/src/main/0000775000175000017500000000000012165015352016142 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/mdo/0000775000175000017500000000000012165015352016721 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/mdo/antlrOptions.mdo0000664000175000017500000000331710773161441022126 0ustar ebourgebourg antlroptions antlrOptions package org.codehaus.mojo.antlr.options Grammar A Grammar parameter. 1.0.0 name The grammar file name. 1.0.0 String true glib Colon separated or semicolon separated supergrammar file names. 1.0.0 String true antlr-maven-plugin-2.2/src/main/resources/0000775000175000017500000000000012165015352020154 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/resources/antlr-report.properties0000664000175000017500000000222010773161441024723 0ustar ebourgebourg# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. report.name=Antlr Grammars report.description=Generated Antlr report from grammars. report.title=Antlr Grammar Report report.overview.title=Overview report.overview.intro=This project uses Antlr for constructing recognizers, compilers, and translators from grammatical descriptions. report.grammars.title=Grammars report.grammars.noreport=No grammar report was generated from Antlr. antlr-maven-plugin-2.2/src/main/resources/antlr-report_fr.properties0000664000175000017500000000232010773161441025413 0ustar ebourgebourg# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. report.name=Grammaires Antlr report.description=G\u00e9n\u00e9re un rapport Antlr des grammaires. report.title=Rapport des grammaires Antlr report.overview.title=Vue d'ensemble report.overview.intro=Ce projet utilise Antlr pour construire des reconnaisseurs, des compilateurs, et des traducteurs de grammaires. report.grammars.title=Grammaires report.grammars.noreport=Aucun rapport de grammaire n'a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 par Antlr. antlr-maven-plugin-2.2/src/main/java/0000775000175000017500000000000012165015352017063 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/0000775000175000017500000000000012165015352017652 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/0000775000175000017500000000000012165015352021445 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/0000775000175000017500000000000012165015352022411 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/0000775000175000017500000000000012165015352023531 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/AntlrHtmlReport.java0000664000175000017500000002251511470601304027476 0ustar ebourgebourgpackage org.codehaus.mojo.antlr; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Locale; import org.apache.maven.doxia.siterenderer.Renderer; import org.apache.maven.doxia.siterenderer.RendererException; import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.reporting.AbstractMavenReportRenderer; import org.apache.maven.reporting.MavenReport; import org.apache.maven.reporting.MavenReportException; import org.apache.maven.wagon.PathUtils; import org.codehaus.doxia.sink.Sink; import org.codehaus.plexus.i18n.I18N; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.StringUtils; /** * Generates Antlr documentation from grammar files. * * @author Vincent Siveton * @version $Id: AntlrHtmlReport.java 13111 2010-11-16 22:16:36Z pgier $ * @goal html * @see Command Line Options */ public class AntlrHtmlReport extends AbstractAntlrMojo implements MavenReport { // ---------------------------------------------------------------------- // Report Parameters // ---------------------------------------------------------------------- /** * Generates the site report * * @component */ private Renderer siteRenderer; /** * Internationalization. * * @component */ protected I18N i18n; /** * Specifies the destination directory where Antlr generates HTML files. * * @parameter default-value="${project.build.directory}/generated-site/antlr" */ private File reportOutputDirectory; /** * The name of the Antlr report. * * @parameter expression="${name}" default-value="Antlr Grammars" */ private String name; /** * The description of the Antlr report. * * @parameter expression="${description}" default-value="Generated Antlr report from grammars." */ private String description; /** * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale) */ public String getName( Locale locale ) { if ( StringUtils.isEmpty( name ) ) { return i18n.getString( "antlr-report", locale, "report.name" ); } return "Antlr Grammars"; } /** * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale) */ public String getDescription( Locale locale ) { if ( StringUtils.isEmpty( description ) ) { return i18n.getString( "antlr-report", locale, "report.description" ); } return description; } /** * @see org.codehaus.mojo.antlr.AbstractAntlrMojo#addArgs(java.util.List) */ protected void addArgs( List arguments ) { // ---------------------------------------------------------------------- // See http://www.antlr2.org/doc/options.html#Command%20Line%20Options // ---------------------------------------------------------------------- arguments.add( "-html" ); } /** * @see org.apache.maven.reporting.MavenReport#generate(org.codehaus.doxia.sink.Sink, java.util.Locale) */ public void generate( Sink sink, Locale locale ) throws MavenReportException { outputDirectory = getReportOutputDirectory(); try { executeAntlr(); } catch ( MojoExecutionException e ) { throw new MavenReportException( "Antlr execution failed: " + e.getMessage(), e ); } AntlrRenderer r = new AntlrRenderer( sink, outputDirectory, i18n, Locale.ENGLISH ); r.render(); } /** * @see org.apache.maven.reporting.MavenReport#getOutputName() */ public String getOutputName() { return "antlr/index"; } /** * @see org.apache.maven.reporting.MavenReport#isExternalReport() */ public boolean isExternalReport() { return false; } /** * @see org.apache.maven.reporting.MavenReport#canGenerateReport() */ public boolean canGenerateReport() { return true; } /** * @see org.apache.maven.reporting.MavenReport#getCategoryName() */ public String getCategoryName() { return CATEGORY_PROJECT_REPORTS; } /** * @see org.apache.maven.reporting.MavenReport#getReportOutputDirectory() */ public File getReportOutputDirectory() { if ( reportOutputDirectory == null ) { return outputDirectory; } return reportOutputDirectory; } /** * @see org.apache.maven.reporting.MavenReport#setReportOutputDirectory(java.io.File) */ public void setReportOutputDirectory( File reportOutputDirectory ) { if ( ( reportOutputDirectory != null ) && ( !reportOutputDirectory.getAbsolutePath().endsWith( "antlr" ) ) ) { this.reportOutputDirectory = new File( reportOutputDirectory, "antlr" ); } else { this.reportOutputDirectory = reportOutputDirectory; } } /** * @see org.apache.maven.reporting.AbstractMavenReport#execute() */ public void execute() throws MojoExecutionException, MojoFailureException { try { SiteRendererSink sink = siteRenderer.createSink( getReportOutputDirectory(), getOutputName() + ".html" ); generate( sink, Locale.getDefault() ); } catch ( RendererException e ) { throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e ); } catch ( IOException e ) { throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e ); } catch ( MavenReportException e ) { throw new MojoExecutionException( "An error has occurred in " + getName( Locale.ENGLISH ) + " report generation.", e ); } } /** * Renderer report */ private static class AntlrRenderer extends AbstractMavenReportRenderer { private File outputDirectory; private I18N i18n; private Locale locale; AntlrRenderer( Sink sink, File outputDirectory, I18N i18n, Locale locale ) { super( sink ); this.outputDirectory = outputDirectory; this.i18n = i18n; this.locale = locale; } /** * @see org.apache.maven.reporting.MavenReportRenderer#getTitle() */ public String getTitle() { return i18n.getString( "antlr-report", locale, "report.title" ); } /** * @see org.apache.maven.reporting.AbstractMavenReportRenderer#renderBody() */ public void renderBody() { startSection( i18n.getString( "antlr-report", locale, "report.overview.title" ) ); paragraph( i18n.getString( "antlr-report", locale, "report.overview.intro" ) ); endSection(); startSection( i18n.getString( "antlr-report", locale, "report.grammars.title" ) ); try { List htmlFiles = FileUtils.getFiles( outputDirectory, "**/*.html", "**/*index.html" ); if ( htmlFiles.isEmpty() ) { sink.text( i18n.getString( "antlr-report", locale, "report.grammars.noreport" ) ); } else { sink.list(); for ( Iterator it = htmlFiles.iterator(); it.hasNext(); ) { File current = (File) it.next(); sink.listItem(); sink.link( PathUtils.toRelative( outputDirectory, current.getAbsolutePath() ) ); sink.text( StringUtils.replace( current.getName(), ".html", "" ) ); sink.link_(); sink.listItem_(); } sink.list_(); } } catch ( IOException e ) { throw new RuntimeException( "IOException: " + e.getMessage(), e ); } endSection(); sink.flush(); sink.close(); } } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/Environment.java0000664000175000017500000000211611470601304026674 0ustar ebourgebourg/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.codehaus.mojo.antlr; import java.io.File; import org.apache.maven.plugin.logging.Log; /** * TODO : javadoc * * @author Steve Ebersole */ public interface Environment { public Log getLog(); public File getSourceDirectory(); public File getOutputDirectory(); } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/proxy/0000775000175000017500000000000012165015352024712 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/proxy/Helper.java0000664000175000017500000000715611470601304027001 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.proxy; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.net.URLClassLoader; import java.net.URL; import java.net.MalformedURLException; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; /** * TODO : javadoc * * @author Steve Ebersole */ public class Helper { public static final Class[] NO_ARG_SIGNATURE = new Class[0]; public static final Class[] STRING_ARG_SIGNATURE = new Class[] { String.class }; public static final Object[] NO_ARGS = new Object[0]; private final URLClassLoader antlrClassLoader; private final Class antlrToolClass; private final Class antlrPreprocessorToolClass; private final Class antlrHierarchyClass; private final Class antlrGrammarFileClass; private final Class antlrGrammarClass; private final Class antlrOptionClass; private final Class antlrIndexedVectorClass; public Helper( Artifact antlrArtifact ) throws MojoExecutionException { try { this.antlrClassLoader = new URLClassLoader( new URL[] { antlrArtifact.getFile().toURL() }, ClassLoader.getSystemClassLoader() ); } catch ( MalformedURLException e ) { throw new MojoExecutionException( "Unable to resolve antlr:antlr artifact url", e ); } antlrToolClass = loadAntlrClass( "antlr.Tool" ); antlrPreprocessorToolClass = loadAntlrClass( "antlr.preprocessor.Tool" ); antlrHierarchyClass = loadAntlrClass( "antlr.preprocessor.Hierarchy" ); antlrGrammarFileClass = loadAntlrClass( "antlr.preprocessor.GrammarFile" ); antlrGrammarClass = loadAntlrClass( "antlr.preprocessor.Grammar" ); antlrOptionClass = loadAntlrClass( "antlr.preprocessor.Option" ); antlrIndexedVectorClass = loadAntlrClass( "antlr.collections.impl.IndexedVector" ); } private Class loadAntlrClass( String className ) throws MojoExecutionException { try { return antlrClassLoader.loadClass( className ); } catch ( ClassNotFoundException e ) { throw new MojoExecutionException( "could not load Antlr class :" + className, e ); } } public Class getAntlrToolClass() { return antlrToolClass; } public Class getAntlrPreprocessorToolClass() { return antlrPreprocessorToolClass; } public Class getAntlrHierarchyClass() { return antlrHierarchyClass; } public Class getAntlrGrammarFileClass() { return antlrGrammarFileClass; } public Class getAntlrGrammarClass() { return antlrGrammarClass; } public Class getAntlrOptionClass() { return antlrOptionClass; } public Class getAntlrIndexedVectorClass() { return antlrIndexedVectorClass; } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/proxy/Tool.java0000664000175000017500000000315411470601304026471 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.proxy; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.mojo.antlr.Environment; /** * TODO : javadoc * * @author Steve Ebersole */ public class Tool { private final Environment environment; private final Object antlrTool; public Tool( Environment environment, Helper helper ) throws MojoExecutionException { try { antlrTool = helper.getAntlrToolClass().newInstance(); } catch ( Throwable t ) { throw new MojoExecutionException( "Unable to instantiate antlr.Tool", t ); } this.environment = environment; } public Object getAntlrTool() { return antlrTool; } public Environment getEnvironment() { return environment; } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/metadata/0000775000175000017500000000000012165015352025311 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/metadata/GrammarFile.java0000664000175000017500000000350011470601304030334 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.metadata; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.List; import java.util.ArrayList; /** * TODO : javadoc * * @author Steve Ebersole */ public class GrammarFile { private final String id; private final String fileName; private final String[] glibs; private String packageName; private List grammars = new ArrayList(); public GrammarFile( String id, String fileName, String[] glibs ) { this.id = id; this.fileName = fileName; this.glibs = glibs; } public String getId() { return id; } public String getFileName() { return fileName; } public String[] getGlibs() { return glibs; } public String getPackageName() { return packageName; } void setPackageName( String packageName ) { this.packageName = packageName; } void addGrammar( Grammar grammar ) { grammars.add( grammar ); } public List getGrammars() { return grammars; } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/metadata/MetadataExtracter.java0000664000175000017500000002625511470601304031564 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.metadata; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.io.File; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.Enumeration; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.mojo.antlr.Environment; import org.codehaus.mojo.antlr.proxy.Helper; import org.codehaus.plexus.util.StringUtils; /** * TODO : javadoc * * @author Steve Ebersole */ public class MetadataExtracter { private final Helper helper; private final Environment environment; private final Class antlrHierarchyClass; public MetadataExtracter( Environment environment, Helper helper ) throws MojoExecutionException { this.environment = environment; this.helper = helper; this.antlrHierarchyClass = helper.getAntlrHierarchyClass(); } public XRef processMetadata( org.codehaus.mojo.antlr.options.Grammar[] grammars ) throws MojoExecutionException { Object hierarchy; Method readGrammarFileMethod; Method getFileMethod; try { Object antlrTool = helper.getAntlrToolClass().newInstance(); Constructor ctor = antlrHierarchyClass.getConstructor( new Class[] { helper.getAntlrToolClass() } ); hierarchy = ctor.newInstance( new Object[] { antlrTool } ); readGrammarFileMethod = antlrHierarchyClass.getMethod( "readGrammarFile", Helper.STRING_ARG_SIGNATURE ); getFileMethod = antlrHierarchyClass.getMethod( "getFile", Helper.STRING_ARG_SIGNATURE ); } catch ( Throwable t ) { throw new MojoExecutionException( "Unable to instantiate Antlr preprocessor tool", causeToUse( t ) ); } ArrayList files = new ArrayList(); for ( int i = 0; i < grammars.length; i++ ) { String grammarName = grammars[i].getName().trim(); if ( StringUtils.isEmpty( grammarName ) ) { environment.getLog().info( "Empty grammar in the configuration; skipping." ); continue; } File grammar = new File( environment.getSourceDirectory(), grammarName ); if ( !grammar.exists() ) { throw new MojoExecutionException( "The grammar '" + grammar.getAbsolutePath() + "' doesnt exist." ); } String grammarFilePath = grammar.getPath(); GrammarFile grammarFile = new GrammarFile( grammarName, grammarFilePath, StringUtils.isNotEmpty( grammars[i].getGlib() ) ? StringUtils.split( grammars[i].getGlib(), ":," ) : new String[0] ); // :( antlr.preprocessor.GrammarFile's only access to package is through a protected field :( try { BufferedReader in = new BufferedReader( new FileReader( grammar ) ); try { String line; while ( ( line = in.readLine() ) != null ) { line = line.trim(); if ( line.startsWith( "package" ) && line.endsWith( ";" ) ) { grammarFile.setPackageName( line.substring( 8, line.length() - 1 ) ); break; } } } finally { try { in.close(); } catch ( IOException ioe ) { } } } catch ( IOException e ) { e.printStackTrace(); } files.add( grammarFile ); try { readGrammarFileMethod.invoke( hierarchy, new Object[] { grammarFilePath } ); } catch ( Throwable t ) { throw new MojoExecutionException( "Unable to use Antlr preprocessor to read grammar file", causeToUse( t ) ); } } XRef xref = new XRef( hierarchy ); Iterator itr = files.iterator(); while ( itr.hasNext() ) { final GrammarFile gf = (GrammarFile) itr.next(); String grammarFilePath = gf.getFileName(); try { Object antlrGrammarFileDef = getFileMethod.invoke( hierarchy, new Object[] { grammarFilePath } ); intrepretMetadata( gf, antlrGrammarFileDef ); xref.addGrammarFile( gf ); } catch ( Throwable t ) { throw new MojoExecutionException( "Unable to build grammar metadata", causeToUse( t ) ); } } return xref; } private void intrepretMetadata( GrammarFile gf, Object antlrGrammarFileDef ) throws MojoExecutionException { // try { // Field headerActionField = helper.getAntlrGrammarFileClass().getDeclaredField( "headerAction" ); // headerActionField.setAccessible( true ); // String header = ( String ) headerActionField.get( antlrGrammarFileDef ); // if ( StringUtils.isNotEmpty( header ) ) { // // locate the package declaration... // StringTokenizer tokenizer = new StringTokenizer( header, System.getProperty("line.separator") ); // while ( tokenizer.hasMoreTokens() ) { // final String token = tokenizer.nextToken().trim(); // if ( token.startsWith( "package " ) && token.endsWith( ";" ) ) { // gf.setPackageName( token.substring( 8, token.length() -1 ) ); // } // } // } // } // catch ( Throwable t ) { // throw new MojoExecutionException( "Error attempting to locate grammar package name", t ); // } try { Object grammarsVector = helper.getAntlrGrammarFileClass().getMethod( "getGrammars", Helper.NO_ARG_SIGNATURE ).invoke( antlrGrammarFileDef, Helper.NO_ARGS ); Enumeration grammars = (Enumeration) helper.getAntlrIndexedVectorClass().getMethod( "elements", Helper.NO_ARG_SIGNATURE ).invoke( grammarsVector, Helper.NO_ARGS ); while ( grammars.hasMoreElements() ) { Grammar grammar = new Grammar( gf ); intrepret( grammar, grammars.nextElement() ); } } catch ( Throwable t ) { throw new MojoExecutionException( "Error attempting to access grammars within grammar file", t ); } } private void intrepret( Grammar grammar, Object antlrGrammarDef ) throws MojoExecutionException { try { Method getNameMethod = helper.getAntlrGrammarClass().getDeclaredMethod( "getName", Helper.NO_ARG_SIGNATURE ); getNameMethod.setAccessible( true ); String name = (String) getNameMethod.invoke( antlrGrammarDef, Helper.NO_ARGS ); grammar.setClassName( name ); Method getSuperGrammarNameMethod = helper.getAntlrGrammarClass().getMethod( "getSuperGrammarName", Helper.NO_ARG_SIGNATURE ); getSuperGrammarNameMethod.setAccessible( true ); String superGrammarName = (String) getSuperGrammarNameMethod.invoke( antlrGrammarDef, Helper.NO_ARGS ); grammar.setSuperGrammarName( superGrammarName ); Method getOptionsMethod = helper.getAntlrGrammarClass().getMethod( "getOptions", Helper.NO_ARG_SIGNATURE ); getOptionsMethod.setAccessible( true ); Object options = getOptionsMethod.invoke( antlrGrammarDef, Helper.NO_ARGS ); Method getElementMethod = helper.getAntlrIndexedVectorClass().getMethod( "getElement", new Class[] { Object.class } ); getElementMethod.setAccessible( true ); Method getRHSMethod = helper.getAntlrOptionClass().getMethod( "getRHS", Helper.NO_ARG_SIGNATURE ); getRHSMethod.setAccessible( true ); Object importVocabOption = getElementMethod.invoke( options, new Object[] { "importVocab" } ); if ( importVocabOption != null ) { String importVocab = (String) getRHSMethod.invoke( importVocabOption, Helper.NO_ARGS ); if ( importVocab != null ) { importVocab = importVocab.trim(); if ( importVocab.endsWith( ";" ) ) { importVocab = importVocab.substring( 0, importVocab.length() - 1 ); } grammar.setImportVocab( importVocab ); } } Object exportVocabOption = getElementMethod.invoke( options, new Object[] { "exportVocab" } ); if ( exportVocabOption != null ) { String exportVocab = (String) getRHSMethod.invoke( exportVocabOption, Helper.NO_ARGS ); if ( exportVocab != null ) { exportVocab = exportVocab.trim(); if ( exportVocab.endsWith( ";" ) ) { exportVocab = exportVocab.substring( 0, exportVocab.length() - 1 ); } } grammar.setExportVocab( exportVocab ); } } catch ( Throwable t ) { throw new MojoExecutionException( "Error accessing Antlr grammar metadata", t ); } } private Throwable causeToUse( Throwable throwable ) { if ( throwable instanceof InvocationTargetException ) { return ( (InvocationTargetException) throwable ).getTargetException(); } else { return throwable; } } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/metadata/Grammar.java0000664000175000017500000000502211470601304027535 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.metadata; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import org.codehaus.plexus.util.StringUtils; /** * TODO : javadoc * * @author Steve Ebersole */ public class Grammar { private final GrammarFile grammarFile; private String className; private String superGrammarName; private String importVocab; private String exportVocab; public Grammar( GrammarFile grammarFile ) { this.grammarFile = grammarFile; grammarFile.addGrammar( this ); } public GrammarFile getGrammarFile() { return grammarFile; } public String getClassName() { return className; } public void setClassName( String className ) { this.className = className; } public String getSuperGrammarName() { return superGrammarName; } public void setSuperGrammarName( String superGrammarName ) { this.superGrammarName = superGrammarName; } public String getImportVocab() { return importVocab; } public void setImportVocab( String importVocab ) { this.importVocab = importVocab; } public String getExportVocab() { return exportVocab; } public void setExportVocab( String exportVocab ) { this.exportVocab = exportVocab; } public String getPackageName() { return getGrammarFile().getPackageName(); } public String determineGeneratedParserPath() { if ( StringUtils.isEmpty( getPackageName() ) ) { return getClassName() + ".java"; } else { return getPackageName().replace( '.', File.separatorChar ) + File.separatorChar + getClassName() + ".java"; } } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/metadata/XRef.java0000664000175000017500000000526511470601304027024 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.metadata; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.LinkedHashMap; import java.util.HashMap; import java.util.Iterator; /** * TODO : javadoc * * @author Steve Ebersole */ public class XRef { private final Object antlrHierarchy; private LinkedHashMap filesById = new LinkedHashMap(); private HashMap filesByExportVocab = new HashMap(); private HashMap filesByClassName = new HashMap(); public XRef( Object antlrHierarchy ) { this.antlrHierarchy = antlrHierarchy; } public Object getAntlrHierarchy() { return antlrHierarchy; } void addGrammarFile( GrammarFile grammarFile ) { filesById.put( grammarFile.getId(), grammarFile ); Iterator itr = grammarFile.getGrammars().iterator(); while ( itr.hasNext() ) { final Grammar grammar = (Grammar) itr.next(); filesByClassName.put( grammar.getClassName(), grammarFile ); if ( grammar.getExportVocab() != null ) { GrammarFile old = (GrammarFile) filesByExportVocab.put( grammar.getExportVocab(), grammarFile ); if ( old != null && old != grammarFile ) { System.out.println( "[WARNING] : multiple grammars defined the same exportVocab : " + grammar.getExportVocab() ); } } } } public Iterator iterateGrammarFiles() { return filesById.values().iterator(); } public GrammarFile getGrammarFileById( String id ) { return (GrammarFile) filesById.get( id ); } public GrammarFile getGrammarFileByClassName( String className ) { return (GrammarFile) filesByClassName.get( className ); } public GrammarFile getGrammarFileByExportVocab( String exportVocab ) { return (GrammarFile) filesByExportVocab.get( exportVocab ); } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/AbstractAntlrMojo.java0000664000175000017500000005515211470601304027771 0ustar ebourgebourgpackage org.codehaus.mojo.antlr; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Pattern; import java.lang.reflect.InvocationTargetException; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.CommandLine; import org.codehaus.mojo.antlr.options.Grammar; import org.codehaus.mojo.antlr.proxy.Helper; import org.codehaus.mojo.antlr.metadata.MetadataExtracter; import org.codehaus.mojo.antlr.metadata.XRef; import org.codehaus.mojo.antlr.plan.GenerationPlan; import org.codehaus.mojo.antlr.plan.GenerationPlanBuilder; import org.codehaus.plexus.util.StringOutputStream; import org.codehaus.plexus.util.StringUtils; /** * Base class with majority of Antlr functionalities. * * @author Vincent Siveton * @version $Id: AbstractAntlrMojo.java 13111 2010-11-16 22:16:36Z pgier $ */ public abstract class AbstractAntlrMojo extends AbstractMojo implements Environment { // ---------------------------------------------------------------------- // Mojo parameters // ---------------------------------------------------------------------- /** * Specifies the Antlr directory containing grammar files. * * @parameter default-value="${basedir}/src/main/antlr" */ protected File sourceDirectory; /** * The Maven Project Object * * @parameter expression="${project}" * @readonly */ protected MavenProject project; /** * The maven project's helper. * * @component role="org.apache.maven.project.MavenProjectHelper" * @readonly */ private MavenProjectHelper projectHelper; // ---------------------------------------------------------------------- // Antlr parameters // See http://www.antlr2.org/doc/options.html#Command%20Line%20Options // ---------------------------------------------------------------------- /** * Specifies the destination directory where Antlr should generate files.
* See Command Line Options * * @parameter default-value="${project.build.directory}/generated-sources/antlr" */ protected File outputDirectory; /** * Comma separated grammar file names or grammar pattern file names present in the sourceDirectory * directory.
* See Command Line Options * * @parameter expression="${grammars}" */ protected String grammars; /** * Grammar list presents in the sourceDirectory directory.
* See Command Line Options
* Example: * *
     * <grammarDefs>
* <grammar>
* <name>myGrammar.g</name>
* <glib>mySuperGrammar.g;myOtherSuperGrammar.g</glib>
* </grammar>
* </grammarDefs> *
* * @parameter expression="${grammarDefs}" */ protected Grammar[] grammarDefs; /** * Launch the ParseView debugger upon parser invocation.
* See Command Line Options * * @parameter expression="${debug}" default-value="false" */ private boolean debug; /** * Generate a text file from your grammar with a lot of debugging info.
* See Command Line Options * * @parameter expression="${diagnostic}" default-value="false" */ private boolean diagnostic; /** * Have all rules call traceIn/traceOut.
* See Command Line Options * * @parameter expression="${trace}" default-value="false" */ private boolean trace; /** * Have parser rules call traceIn/traceOut.
* See Command Line Options * * @parameter expression="${traceParser}" default-value="false" */ private boolean traceParser; /** * Have lexer rules call traceIn/traceOut.
* See Command Line Options * * @parameter expression="${traceLexer}" default-value="false" */ private boolean traceLexer; /** * Have tree rules call traceIn/traceOut.
* See Command Line Options * * @parameter expression="${traceTreeParser}" default-value="false" */ private boolean traceTreeParser; public File getSourceDirectory() { return sourceDirectory; } public File getOutputDirectory() { return outputDirectory; } /** * @throws MojoExecutionException */ protected void executeAntlr() throws MojoExecutionException { validateParameters(); Artifact antlrArtifact = locateAntlrArtifact(); MetadataExtracter metadataExtracter = new MetadataExtracter( this, new Helper( antlrArtifact ) ); XRef metadata = metadataExtracter.processMetadata( getGrammars() ); Iterator generationPlans = new GenerationPlanBuilder( this ).buildGenerationPlans( metadata ).iterator(); while ( generationPlans.hasNext() ) { final GenerationPlan plan = (GenerationPlan) generationPlans.next(); if ( !plan.isOutOfDate() ) { getLog().info( "grammar [" + plan.getId() + "] was up-to-date; skipping" ); continue; } getLog().info( "performing grammar generation [" + plan.getId() + "]" ); performGeneration( plan, antlrArtifact ); } if ( project != null ) { projectHelper.addResource( project, outputDirectory.getAbsolutePath(), Collections.singletonList( "**/**.txt" ), new ArrayList() ); project.addCompileSourceRoot( outputDirectory.getAbsolutePath() ); } } protected final Artifact locateAntlrArtifact() throws NoAntlrDependencyDefinedException { Artifact antlrArtifact = null; if ( project.getCompileArtifacts() != null ) { Iterator projectArtifacts = project.getCompileArtifacts().iterator(); while ( projectArtifacts.hasNext() ) { final Artifact artifact = (Artifact) projectArtifacts.next(); if ( "antlr".equals( artifact.getGroupId() ) && ( "antlr".equals( artifact.getArtifactId() ) || "antlr-all".equals( artifact.getArtifactId() ) ) ) { antlrArtifact = artifact; break; } } } if ( antlrArtifact == null ) { throw new NoAntlrDependencyDefinedException( "project did not define antlr:antlr depenency" ); } // TODO : enforce specific version range; e.g. [2.7,3.0) ??? return antlrArtifact; } protected void performGeneration( GenerationPlan plan, Artifact antlrArtifact ) throws MojoExecutionException { if ( !plan.getGenerationDirectory().getParentFile().exists() ) { plan.getGenerationDirectory().getParentFile().mkdirs(); } // ---------------------------------------------------------------------- // Wrap arguments // Note: grammar file should be last // ---------------------------------------------------------------------- List arguments = new LinkedList(); addArgIf( arguments, debug, "-debug" ); addArgIf( arguments, diagnostic, "-diagnostic" ); addArgIf( arguments, trace, "-trace" ); addArgIf( arguments, traceParser, "-traceParser" ); addArgIf( arguments, traceLexer, "-traceLexer" ); addArgIf( arguments, traceTreeParser, "-traceTreeParser" ); addArgs( arguments ); arguments.add( "-o" ); arguments.add( plan.getGenerationDirectory().getPath() ); if ( plan.getCollectedSuperGrammarIds().size() > 0 ) { arguments.add( "-glib" ); StringBuffer buffer = new StringBuffer(); Iterator ids = plan.getCollectedSuperGrammarIds().iterator(); while ( ids.hasNext() ) { buffer.append( new File( sourceDirectory, (String) ids.next() ) ); if ( ids.hasNext() ) { buffer.append( ';' ); } } arguments.add( buffer.toString() ); } arguments.add( plan.getSource().getPath() ); String[] args = (String[]) arguments.toArray( new String[arguments.size()] ); if ( plan.getImportVocabTokenTypesDirectory() != null && !plan.getImportVocabTokenTypesDirectory().equals( plan.getGenerationDirectory() ) ) { // we need to spawn a new process to properly set up PWD CommandLine commandLine = new CommandLine( "java" ); commandLine.addArgument( "-classpath", false ); commandLine.addArgument( generateClasspathForProcessSpawning( antlrArtifact ), true ); commandLine.addArgument( "antlr.Tool", false ); commandLine.addArguments( args, true ); DefaultExecutor executor = new DefaultExecutor(); executor.setWorkingDirectory( plan.getImportVocabTokenTypesDirectory() ); try { executor.execute( commandLine ); } catch ( IOException e ) { getLog().warn( "Error spawning process to execute antlr tool : " + e.getMessage() ); } return; } // ---------------------------------------------------------------------- // Call Antlr // ---------------------------------------------------------------------- if ( getLog().isDebugEnabled() ) { getLog().debug( "antlr args=\n" + StringUtils.join( args, "\n" ) ); } boolean failedSetManager = false; SecurityManager oldSm = null; try { oldSm = System.getSecurityManager(); System.setSecurityManager( NoExitSecurityManager.INSTANCE ); } catch ( SecurityException ex ) { // ANTLR-12 oldSm = null; failedSetManager = true; // ignore, in embedded environment the security manager can already be set. // in such a case assume the exit call is handled properly.. getLog().warn( "Cannot set custom SecurityManager. " + "Antlr's call to System.exit() can cause application shutdown " + "if not handled by the current SecurityManager." ); } String originalUserDir = null; if ( plan.getImportVocabTokenTypesDirectory() != null ) { originalUserDir = System.getProperty( "user.dir" ); System.setProperty( "user.dir", plan.getImportVocabTokenTypesDirectory().getPath() ); } PrintStream oldErr = System.err; OutputStream errOS = new StringOutputStream(); PrintStream err = new PrintStream( errOS ); System.setErr( err ); try { executeAntlrInIsolatedClassLoader( (String[]) arguments.toArray( new String[0] ), antlrArtifact ); } catch ( SecurityException e ) { if ( e.getMessage().equals( "exitVM-0" ) || e.getClass().getName().equals( "org.netbeans.core.execution.ExitSecurityException" ) ) // netbeans // IDE Sec // Manager. { // ANTLR-12 // now basically every secutiry manager could set different message, how to handle in generic way? // probably only by external execution // / in case of NetBeans SecurityManager, it's not possible to distinguish exit codes, rather swallow // than fail. getLog().debug( e ); } else { throw new MojoExecutionException( "Antlr execution failed: " + e.getMessage() + "\n Error output:\n" + errOS, e ); } } finally { if ( originalUserDir != null ) { System.setProperty( "user.dir", originalUserDir ); } if ( !failedSetManager ) { System.setSecurityManager( oldSm ); } System.setErr( oldErr ); System.err.println( errOS.toString() ); } } private String generateClasspathForProcessSpawning( Artifact antlrArtifact ) { // todo : is maven by itself enough for the generation??? return antlrArtifact.getFile().getPath(); } private void executeAntlrInIsolatedClassLoader( String[] args, Artifact antlrArtifact ) throws MojoExecutionException { try { URLClassLoader classLoader = new URLClassLoader( new URL[] { antlrArtifact.getFile().toURL() }, ClassLoader.getSystemClassLoader() ); Class toolClass = classLoader.loadClass( "antlr.Tool" ); toolClass.getMethod( "main", new Class[] { String[].class } ).invoke( null, new Object[] { args } ); } catch ( MalformedURLException e ) { throw new MojoExecutionException( "Unable to resolve antlr:antlr artifact url", e ); } catch ( ClassNotFoundException e ) { throw new MojoExecutionException( "could not locate antlr.Tool class" ); } catch ( NoSuchMethodException e ) { throw new MojoExecutionException( "error locating antlt.Tool#main", e ); } catch ( InvocationTargetException e ) { throw new MojoExecutionException( "error perforing antlt.Tool#main", e.getTargetException() ); } catch ( IllegalAccessException e ) { throw new MojoExecutionException( "error perforing antlt.Tool#main", e ); } } /** * Add arguments to be included in Antlr call * * @param arguments */ protected abstract void addArgs( List arguments ); /** * Convenience method to add an argument * * @param arguments * @param b * @param value */ protected static void addArgIf( List arguments, boolean b, String value ) { if ( b ) { arguments.add( value ); } } /** * @param grammar * @param outputDir * @return generated file * @throws IOException */ private File getGeneratedFile( String grammar, File outputDir ) throws IOException { String generatedFileName = null; String packageName = ""; BufferedReader in = new BufferedReader( new FileReader( grammar ) ); String line; while ( ( line = in.readLine() ) != null ) { line = line.trim(); int extendsIndex = line.indexOf( " extends " ); if ( line.startsWith( "class " ) && extendsIndex > -1 ) { generatedFileName = line.substring( 6, extendsIndex ).trim(); break; } else if ( line.startsWith( "package" ) ) { packageName = line.substring( 8 ).trim(); } } in.close(); if ( generatedFileName == null ) { throw new IOException( "Unable to generate the output file name: is the grammar '" + grammar + "' valide?" ); } File genFile = null; if ( "".equals( packageName ) ) { genFile = new File( outputDir, generatedFileName + ".java" ); } else { String packagePath = packageName.replace( '.', File.separatorChar ); packagePath = packagePath.replace( ';', File.separatorChar ); genFile = new File( new File( outputDir, packagePath ), generatedFileName + ".java" ); } return genFile; } /** * grammars or grammarDefs parameters is required * * @throws MojoExecutionException */ private void validateParameters() throws MojoExecutionException { if ( ( StringUtils.isEmpty( grammars ) ) && ( ( grammarDefs == null ) || ( grammarDefs.length == 0 ) ) ) { StringBuffer msg = new StringBuffer(); msg.append( "Antlr plugin parameters are invalid/missing." ).append( '\n' ); msg.append( "Inside the definition for plugin 'antlr-maven-plugin' specify the following:" ).append( '\n' ); msg.append( '\n' ); msg.append( "" ).append( '\n' ); msg.append( " VALUE" ).append( '\n' ); msg.append( "- OR - " ).append( '\n' ); msg.append( " VALUE" ).append( '\n' ); msg.append( "" ).append( '\n' ); throw new MojoExecutionException( msg.toString() ); } } /** * Get the list of all grammars to be compiled. The grammars variable can be a list of file or patterns. For * instance, one can use *.g instead of a full list of grammar names. Be aware that sometime the grammar order is * important, and that patterns won't keep this order, but we can still combine both elements( ordered names first, * then the patterns). File name won't be added twice in the list of files. * * @return an array of grammar from grammars and grammarDefs variables */ private Grammar[] getGrammars() { List grammarList = new ArrayList(); Set grammarSet = new HashSet(); if ( StringUtils.isNotEmpty( grammars ) ) { StringTokenizer st = new StringTokenizer( grammars, ", " ); while ( st.hasMoreTokens() ) { String currentGrammar = st.nextToken().trim(); if ( StringUtils.isNotEmpty( currentGrammar ) ) { // Check if some pattern has been used if ( ( currentGrammar.indexOf( '*' ) != -1 ) || ( currentGrammar.indexOf( '?' ) != -1 ) ) { // We first have to 'protect' the '.', and transform patterns // to regexp, substituting '*' to '.*' and '?' to '.' final String transformedGrammar = currentGrammar.replaceAll( "\\.", "\\\\." ).replaceAll( "\\*", ".*" ).replaceAll( "\\?", "." ); // Filter the source directory String[] dir = sourceDirectory.list( new FilenameFilter() { public boolean accept( File dir, String s ) { return Pattern.matches( transformedGrammar, s ); } } ); if ( ( dir != null ) && ( dir.length != 0 ) ) { for ( int i = 0; i < dir.length; i++ ) { // Just add fles which are not in the set // of files already seen. if ( !grammarSet.contains( dir[i] ) ) { Grammar grammar = new Grammar(); grammar.setName( dir[i] ); grammarList.add( grammar ); } } } } else { if ( !grammarSet.contains( currentGrammar ) ) { Grammar grammar = new Grammar(); grammar.setName( currentGrammar ); grammarList.add( grammar ); } } } } } if ( grammarDefs != null ) { grammarList.addAll( Arrays.asList( grammarDefs ) ); } return (Grammar[]) grammarList.toArray( new Grammar[0] ); } public static class NoAntlrDependencyDefinedException extends MojoExecutionException { public NoAntlrDependencyDefinedException( String s ) { super( s ); } } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/AntlrPlugin.java0000664000175000017500000000401111470601304026623 0ustar ebourgebourgpackage org.codehaus.mojo.antlr; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.List; import org.apache.maven.plugin.MojoExecutionException; //---------------------------------------------------------------------- // Don't remove this snippet //---------------------------------------------------------------------- // START SNIPPET: generate-sources-0 /** * Generates files based on grammar files with Antlr tool. * * @goal generate * @phase generate-sources * @requiresDependencyResolution compile * @author Vincent Siveton * @version $Id: AntlrPlugin.java 13111 2010-11-16 22:16:36Z pgier $ */ public class AntlrPlugin extends AbstractAntlrMojo { /** * @see org.apache.maven.plugin.Mojo#execute() */ public void execute() throws MojoExecutionException { executeAntlr(); } // END SNIPPET: generate-sources-0 // ---------------------------------------------------------------------- // Don't remove this snippet // ---------------------------------------------------------------------- /** * @see org.codehaus.mojo.antlr.AbstractAntlrMojo#addArgs(java.util.List) */ protected void addArgs( List arguments ) { // nop } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/NoExitSecurityManager.java0000664000175000017500000000311410773161441030630 0ustar ebourgebourgpackage org.codehaus.mojo.antlr; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.security.Permission; /** * @author Vincent Siveton * @version $Id: NoExitSecurityManager.java 6588 2008-03-28 12:22:57Z bentmann $ */ public class NoExitSecurityManager extends SecurityManager { static final NoExitSecurityManager INSTANCE = new NoExitSecurityManager(); private NoExitSecurityManager() { // nop } /** * @see java.lang.SecurityManager#checkPermission(java.security.Permission) */ public void checkPermission( Permission permission ) { // nop } /** * @see java.lang.SecurityManager#checkExit(int) */ public void checkExit( int status ) { throw new SecurityException( "exitVM-" + status ); } } antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/plan/0000775000175000017500000000000012165015352024463 5ustar ebourgebourgantlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/plan/GenerationPlanBuilder.java0000664000175000017500000001725511470601304031551 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.plan; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.LinkedHashMap; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.io.File; import org.codehaus.mojo.antlr.Environment; import org.codehaus.mojo.antlr.metadata.XRef; import org.codehaus.mojo.antlr.metadata.GrammarFile; import org.codehaus.mojo.antlr.metadata.Grammar; import org.codehaus.plexus.util.StringUtils; /** * TODO : javadoc * * @author Steve Ebersole */ public class GenerationPlanBuilder { private final Environment environment; private final LinkedHashMap generationPlans = new LinkedHashMap(); private XRef metadataXRef; public GenerationPlanBuilder( Environment environment ) { this.environment = environment; } public synchronized List buildGenerationPlans( XRef metadataXRef ) { this.metadataXRef = metadataXRef; Iterator grammarFiles = metadataXRef.iterateGrammarFiles(); while ( grammarFiles.hasNext() ) { final GrammarFile grammarFile = (GrammarFile) grammarFiles.next(); // NOTE : loacteOrBuildGenerationPlan populates the generationPlans map loacteOrBuildGenerationPlan( grammarFile ); } metadataXRef = null; return new ArrayList( generationPlans.values() ); } private GenerationPlan loacteOrBuildGenerationPlan( GrammarFile grammarFile ) { GenerationPlan generationPlan = (GenerationPlan) generationPlans.get( grammarFile.getId() ); if ( generationPlan == null ) { generationPlan = buildGenerationPlan( grammarFile ); } return generationPlan; } private GenerationPlan buildGenerationPlan( GrammarFile grammarFile ) { File generationDirectory = StringUtils.isEmpty( grammarFile.getPackageName() ) ? environment.getOutputDirectory() : new File( environment.getOutputDirectory(), grammarFile.getPackageName().replace( '.', File.separatorChar ) ); GenerationPlan generationPlan = new GenerationPlan( grammarFile.getId(), new File( grammarFile.getFileName() ), generationDirectory, grammarFile.getGlibs() ); File leastRecentGrammarOutput = locateLeastRecentlyModifiedOutputFile( generationDirectory ); // see if the grammar is out-of-date by way super-grammars from user defined glib options for ( int i = 0; i < grammarFile.getGlibs().length; i++ ) { final GrammarFile superGrammarGrammarFile = metadataXRef.getGrammarFileById( grammarFile.getGlibs()[i] ); final GenerationPlan superGrammarGenerationPlan = loacteOrBuildGenerationPlan( superGrammarGrammarFile ); if ( superGrammarGenerationPlan.isOutOfDate() ) { generationPlan.markOutOfDate(); } else if ( superGrammarGenerationPlan.getSource().lastModified() > leastRecentGrammarOutput.lastModified() ) { generationPlan.markOutOfDate(); } } Iterator grammars = grammarFile.getGrammars().iterator(); while ( grammars.hasNext() ) { final Grammar grammar = (Grammar) grammars.next(); final File generatedParserFile = new File( environment.getOutputDirectory(), grammar.determineGeneratedParserPath() ); if ( !generatedParserFile.exists() ) { generationPlan.markOutOfDate(); } else if ( generatedParserFile.lastModified() < generationPlan.getSource().lastModified() ) { generationPlan.markOutOfDate(); } // see if the grammar if out-of-date by way of its super-grammar(s) as gleaned from parsing the grammar file if ( StringUtils.isNotEmpty( grammar.getSuperGrammarName() ) ) { final GrammarFile superGrammarGrammarFile = metadataXRef.getGrammarFileByClassName( grammar.getSuperGrammarName() ); if ( superGrammarGrammarFile != null ) { final GenerationPlan superGrammarGenerationPlan = loacteOrBuildGenerationPlan( superGrammarGrammarFile ); generationPlan.addSuperGrammarId( superGrammarGenerationPlan.getId() ); if ( superGrammarGenerationPlan.isOutOfDate() ) { generationPlan.markOutOfDate(); } else if ( superGrammarGenerationPlan.getSource().lastModified() > generatedParserFile.lastModified() ) { generationPlan.markOutOfDate(); } } } // see if the grammar if out-of-date by way of its importVocab if ( StringUtils.isNotEmpty( grammar.getImportVocab() ) ) { final GrammarFile importVocabGrammarFile = metadataXRef.getGrammarFileByExportVocab( grammar.getImportVocab() ); if ( importVocabGrammarFile == null ) { environment.getLog().warn( "unable to locate grammar exporting specifcied import vocab [" + grammar.getImportVocab() + "]" ); } else if ( importVocabGrammarFile.getId().equals( grammarFile.getId() ) ) { } else { final GenerationPlan importVocabGrammarGenerationPlan = loacteOrBuildGenerationPlan( importVocabGrammarFile ); generationPlan.setImportVocabTokenTypesDirectory( importVocabGrammarGenerationPlan.getGenerationDirectory() ); if ( importVocabGrammarGenerationPlan.isOutOfDate() ) { generationPlan.markOutOfDate(); } else if ( importVocabGrammarGenerationPlan.getSource().lastModified() > generatedParserFile.lastModified() ) { generationPlan.markOutOfDate(); } } } } generationPlans.put( generationPlan.getId(), generationPlan ); return generationPlan; } private static File locateLeastRecentlyModifiedOutputFile( File directory ) { if ( !directory.exists() ) { return null; } File[] contents = directory.listFiles(); if ( contents.length == 0 ) { return null; } File oldest = contents[0]; for ( int i = 1; i < contents.length; i++ ) { if ( contents[i].lastModified() < oldest.lastModified() ) { oldest = contents[i]; } } return oldest; } }antlr-maven-plugin-2.2/src/main/java/org/codehaus/mojo/antlr/plan/GenerationPlan.java0000664000175000017500000000467111470601304030240 0ustar ebourgebourgpackage org.codehaus.mojo.antlr.plan; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.util.LinkedHashSet; /** * TODO : javadoc * * @author Steve Ebersole */ public class GenerationPlan { private final String id; private final File source; private final File generationDirectory; private File importVocabTokenTypesDirectory; private boolean outOfDate; private LinkedHashSet collectedSuperGrammarIds = new LinkedHashSet(); GenerationPlan( String id, File source, File generationDirectory, String[] glibIds ) { this.id = id; this.source = source; this.generationDirectory = generationDirectory; if ( glibIds != null ) { for ( int i = 0; i < glibIds.length; i++ ) { addSuperGrammarId( glibIds[i] ); } } } public String getId() { return id; } public File getSource() { return source; } public File getGenerationDirectory() { return generationDirectory; } void addSuperGrammarId( String id ) { collectedSuperGrammarIds.add( id ); } public LinkedHashSet getCollectedSuperGrammarIds() { return collectedSuperGrammarIds; } public File getImportVocabTokenTypesDirectory() { return importVocabTokenTypesDirectory; } void setImportVocabTokenTypesDirectory( File importVocabTokenTypesDirectory ) { this.importVocabTokenTypesDirectory = importVocabTokenTypesDirectory; } public boolean isOutOfDate() { return outOfDate; } void markOutOfDate() { this.outOfDate = true; } }