Merge branch 'master' of github.com:antlr/antlr4

This commit is contained in:
Terence Parr 2012-12-01 14:38:33 -08:00
commit fc79752748
11 changed files with 485 additions and 601 deletions

8
.gitignore vendored
View File

@ -1,13 +1,19 @@
# Maven build folders
/target/
/tool/target/
/runtime/Java/target/
/gunit/target/
/antlr4-maven-plugin/target/
# Ant build folders
/build/
/dist/
# NetBeans user configuration files
/nbactions.xml
/tool/nbactions.xml
/runtime/Java/nbactions.xml
/antlr4-maven-plugin/nbactions.xml
# IntelliJ projects
*.iml
*.ipr

View File

@ -6,8 +6,22 @@ December 1, 2012
line 2:3 token recognition error at: '\t'
line 2:4 token recognition error at: '\n'
November 30, 2012
* Maven updates (cleanup, unification, and specify Java 6 bootstrap classpath)
November 28, 2012
* Maven updates (uber-jar, manifest details)
November 27, 2012
* Maven updates (prepare for deploying to Sonatype OSS)
* Use efficient bitset tests instead of long chains of operator ==
November 26, 2012
* Maven updates (include sources and javadocs, fix warnings)
* Don't generate action methods for lexer rules not containing an action
* Generated action and sempred methods are private
* Remove unused / problematic methods:

View File

@ -48,135 +48,16 @@
<packaging>maven-plugin</packaging>
<name>ANTLR 4 Maven plugin</name>
<description>Maven plugin for ANTLR 4 grammars</description>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
<developers>
<developer>
<name>Terence Parr</name>
<url>http://antlr.org/wiki/display/~admin/Home</url>
<roles>
<role>Project lead - ANTLR</role>
</roles>
</developer>
<developer>
<name>Sam Harwell</name>
<url>http://tunnelvisionlabs.com</url>
<roles>
<role>Developer</role>
</roles>
</developer>
<developer>
<name>Jim Idle</name>
<url>http://www.temporal-wave.com</url>
<roles>
<role>Originator, version 4.0</role>
</roles>
</developer>
<developer>
<name>David Holroyd</name>
<url>http://david.holroyd.me.uk/</url>
<roles>
<role>Originator - prior version</role>
</roles>
</developer>
<developer>
<name>Kenny MacDermid</name>
<url>mailto:kenny "at" kmdconsulting.ca</url>
<roles>
<role>Contributor - prior versions</role>
</roles>
</developer>
</developers>
<!-- Location of the license description for this project
-->
<licenses>
<license>
<distribution>repo</distribution>
<name>The BSD License</name>
<url>http://www.antlr.org/LICENSE.txt </url>
</license>
</licenses>
<distributionManagement>
<repository>
<id>antlr-repo</id>
<name>ANTLR Testing repository</name>
<url>scpexe://antlr.org/home/mavensync/antlr-repo</url>
</repository>
<snapshotRepository>
<id>antlr-snapshot</id>
<name>ANTLR Testing Snapshot Repository</name>
<url>scpexe://antlr.org/home/mavensync/antlr-snapshot</url>
</snapshotRepository>
<site>
<id>antlr-repo</id>
<name>ANTLR Maven Plugin Web Site</name>
<url>scpexe://antlr.org/home/mavensync/antlr-maven-webs/antlr4-maven-plugin</url>
</site>
</distributionManagement>
<!--
Inform Maven of the ANTLR snapshot repository, which it will
need to consult to get the latest snapshot build of the runtime and tool
if it was not built and installed locally.
-->
<repositories>
<!--
This is the ANTLR repository.
-->
<repository>
<id>antlr-snapshot</id>
<name>ANTLR Testing Snapshot Repository</name>
<url>http://antlr.org/antlr-snapshot</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<!-- Ancilliary information for completeness
-->
<inceptionYear>2009</inceptionYear>
<mailingLists>
<mailingList>
<archive>http://antlr.markmail.org/</archive>
<otherArchives>
<otherArchive>http://www.antlr.org/pipermail/antlr-interest/</otherArchive>
</otherArchives>
<name>ANTLR Users</name>
<subscribe>http://www.antlr.org/mailman/listinfo/antlr-interest/</subscribe>
<unsubscribe>http://www.antlr.org/mailman/options/antlr-interest/</unsubscribe>
<post>antlr-interest@antlr.org</post>
</mailingList>
</mailingLists>
<organization>
<name>ANTLR.org</name>
<url>http://www.antlr.org</url>
</organization>
<!-- ============================================================================= -->
<!--
@ -253,30 +134,8 @@
<defaultGoal>install</defaultGoal>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh-external</artifactId>
<version>2.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArguments>
<Xlint/>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
@ -316,34 +175,6 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@ -1,9 +1,7 @@
/**
[The "BSD licence"]
ANTLR - Copyright (c) 2005-2008 Terence Parr
Maven Plugin - Copyright (c) 2009 Jim Idle
/*
[The "BSD license"]
Copyright (c) 2012 Terence Parr
Copyright (c) 2012 Sam Harwell
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,31 +28,35 @@
*/
package org.antlr.mojo.antlr4;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.ANTLRToolListener;
import org.apache.maven.plugin.logging.Log;
/**
* The Maven plexus container gives us a Log logging provider
* which we can use to install an error listener for the ANTLR
* tool to report errors by.
* This implementation of {@link ANTLRToolListener} reports messages to the
* {@link Log} instance provided by Maven.
*
* @author Sam Harwell
*/
public class Antlr4ErrorLog implements ANTLRToolListener {
private Log log;
private final Log log;
/**
* Instantiate an ANTLR ErrorListner that communicates any messages
* it receives to the Maven error sink.
* Creates an instance of {@link Antlr4ErrorLog}.
*
* @param log The Maven Error Log
* @param log The Maven log
*/
public Antlr4ErrorLog(Log log) {
public Antlr4ErrorLog(@NotNull Log log) {
this.log = log;
}
/**
* Sends an informational message to the Maven log sink.
* {@inheritDoc}
* <p/>
* This implementation passes the message to the Maven log.
*
* @param message The message to send to Maven
*/
@Override
@ -63,7 +65,9 @@ public class Antlr4ErrorLog implements ANTLRToolListener {
}
/**
* Sends an error message from ANTLR analysis to the Maven Log sink.
* {@inheritDoc}
* <p/>
* This implementation passes the message to the Maven log.
*
* @param message The message to send to Maven.
*/
@ -73,7 +77,9 @@ public class Antlr4ErrorLog implements ANTLRToolListener {
}
/**
* Sends a warning message to the Maven log sink.
* {@inheritDoc}
* <p/>
* This implementation passes the message to the Maven log.
*
* @param message
*/

View File

@ -1,43 +1,39 @@
/**
[The "BSD licence"]
/*
[The "BSD license"]
Copyright (c) 2012 Terence Parr
Copyright (c) 2012 Sam Harwell
All rights reserved.
ANTLR - Copyright (c) 2005-2008 Terence Parr
Maven Plugin - Copyright (c) 2009 Jim Idle
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/* ========================================================================
* This is the definitive ANTLR4 Mojo set. All other sets are belong to us.
*/
package org.antlr.mojo.antlr4;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import org.antlr.v4.Tool;
import org.antlr.v4.codegen.CodeGenerator;
import org.antlr.v4.runtime.misc.MultiMap;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.tool.Grammar;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@ -62,104 +58,93 @@ import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Goal that picks up all the ANTLR grammars in a project and moves those that
* are required for generation of the compilable sources into the location
* that we use to compile them, such as target/generated-sources/antlr4 ...
* that we use to compile them, such as {@code target/generated-sources/antlr4}.
*
* @author <a href="mailto:jimi@temporal-wave.com">Jim Idle</a>
* @author Sam Harwell
*/
@Mojo(
name = "antlr",
defaultPhase = LifecyclePhase.PROCESS_SOURCES,
requiresDependencyResolution = ResolutionScope.COMPILE,
requiresProject = true)
public class Antlr4Mojo
extends AbstractMojo {
public class Antlr4Mojo extends AbstractMojo {
// First, let's deal with the options that the ANTLR tool itself
// can be configured by.
//
/**
* If set to true, then after the tool has processed an input grammar file
* it will report variaous statistics about the parser, such as information
* on cyclic DFAs, which rules may use backtracking, and so on.
*/
@Parameter(defaultValue = "false")
protected boolean report;
/**
* If set to true, then the ANTLR tool will print a version of the input
* grammar which is devoid of any actions that may be present in the input file.
*/
@Parameter(defaultValue = "false")
protected boolean printGrammar;
/**
* If set to true, then the code generated by the ANTLR code generator will
* be set to debug mode. This means that when run, the code will 'hang' and
* wait for a debug connection on a TCP port (49100 by default).
*/
@Parameter(defaultValue = "false")
protected boolean debug;
/**
* If set to true, then then the generated parser will compute and report on
* profile information at runtime.
*/
@Parameter(defaultValue = "false")
protected boolean profile;
/**
* If set to true then the ANTLR tool will generate a description of the atn
* for each rule in <a href="http://www.graphviz.org">Dot format</a>
*/
@Parameter(defaultValue = "false")
@Parameter(property = "antlr4.atn", defaultValue = "false")
protected boolean atn;
/**
* If set to true, the generated parser code will log rule entry and exit points
* to stdout as an aid to debugging.
* specify grammar file encoding; e.g., euc-jp
*/
@Parameter
protected String encoding;
/**
* generate parse tree listener (default)
*/
@Parameter(property = "antlr4.listener", defaultValue = "true")
protected boolean listener;
/**
* generate parse tree visitor
*/
@Parameter(property = "antlr4.visitor", defaultValue = "false")
protected boolean visitor;
/**
* treat warnings as errors
*/
@Parameter(property = "antlr4.treatWarningsAsErrors", defaultValue = "false")
protected boolean treatWarningsAsErrors;
/**
* add config set to DFA states
*/
@Parameter(defaultValue = "false")
protected boolean trace;
/**
* If this parameter is set, it indicates that any warning or error messages returned
* by ANLTR, shoould be formatted in the specified way. Currently, ANTLR suports the
* built-in formats of antlr, gnu and vs2005.
*/
@Parameter(defaultValue = "antlr")
protected String messageFormat;
/**
* If this parameter is set to true, then ANTLR will report all sorts of things
* about what it is doing such as the names of files and the version of ANTLR and so on.
*/
@Parameter(defaultValue = "true")
protected boolean verbose;
protected boolean verbose_dfa;
protected boolean force_atn;
protected boolean abstract_recognizer;
/**
* use the ATN simulator for all predictions
*/
@Parameter(property = "antlr4.forceATN", defaultValue = "false")
protected boolean forceATN;
/**
* The number of alts, beyond which ANTLR will not generate a switch statement
* for the DFA.
* A list of grammar options to explicitly specify to the tool. These
* options are passed to the tool using the
* <code>-D&lt;option&gt;=&lt;value&gt;</code> syntax.
*/
@Parameter(defaultValue = "300")
private int maxSwitchCaseLabels;
@Parameter
protected Map<String, String> options;
/**
* The number of alts, below which ANTLR will not choose to generate a switch
* statement over an if statement.
* A list of additional command line arguments to pass to the ANTLR tool.
*/
private int minSwitchAlts;
@Parameter
protected List<String> arguments;
/* --------------------------------------------------------------------
* The following are Maven specific parameters, rather than specificlly
* options that the ANTLR tool can use.
*/
/**
* Provides an explicit list of all the grammars that should
* be included in the generate phase of the plugin. Note that the plugin
@ -185,25 +170,21 @@ public class Antlr4Mojo
*/
@Parameter(property = "project", required = true, readonly = true)
protected MavenProject project;
/**
* Specifies the Antlr directory containing grammar files. For
* antlr version 4.x we default this to a directory in the tree
* called antlr4 because the antlr3 directory is occupied by version
* 3.x grammars.
* Specifies the ANTLR directory containing grammar files.
*/
@Parameter(defaultValue = "${basedir}/src/main/antlr4", required = true)
private File sourceDirectory;
/**
* Location for generated Java files. For antlr version 4.x we default
* this to a directory in the tree called antlr4 because the antlr
* directory is occupied by version 2.x grammars.
* Specify output directory where the Java files are generated.
*/
@Parameter(defaultValue = "${project.build.directory}/generated-sources/antlr4", required = true)
private File outputDirectory;
/**
* Location for imported token files, e.g. <code>.tokens</code> and imported grammars.
* Note that ANTLR will not try to process grammars that it finds to be imported
* into other grammars (in the same processing session).
* Specify location of grammars and tokens files.
*/
@Parameter(defaultValue = "${basedir}/src/main/antlr4/imports")
private File libDirectory;
@ -223,6 +204,7 @@ public class Antlr4Mojo
void addSourceRoot(File outputDir) {
project.addCompileSourceRoot(outputDir.getPath());
}
/**
* An instance of the ANTLR tool build
*/
@ -232,12 +214,11 @@ public class Antlr4Mojo
* The main entry point for this Mojo, it is responsible for converting
* ANTLR 4.x grammars into the target language specified by the grammar.
*
* @throws org.apache.maven.plugin.MojoExecutionException When something is disvocered such as a missing source
* @throws org.apache.maven.plugin.MojoFailureException When something really bad happesn such as not being able to create the ANTLR Tool
* @throws MojoExecutionException When something is discovered such as a missing source
* @throws MojoFailureException When something really bad happens such as not being able to create the ANTLR Tool
*/
@Override
public void execute()
throws MojoExecutionException, MojoFailureException {
public void execute() throws MojoExecutionException, MojoFailureException {
Log log = getLog();
@ -268,16 +249,11 @@ public class Antlr4Mojo
// Flags
//
log.debug("ANTLR: report : " + report);
log.debug("ANTLR: printGrammar : " + printGrammar);
log.debug("ANTLR: debug : " + debug);
log.debug("ANTLR: profile : " + profile);
log.debug("ANTLR: atn : " + atn);
log.debug("ANTLR: trace : " + trace);
log.debug("ANTLR: messageFormat : " + messageFormat);
log.debug("ANTLR: maxSwitchCaseLabels : " + maxSwitchCaseLabels);
log.debug("ANTLR: minSwitchAlts : " + minSwitchAlts);
log.debug("ANTLR: verbose : " + verbose);
}
if (!sourceDirectory.isDirectory()) {
log.info("No ANTLR 4 grammars to compile in " + sourceDirectory.getAbsolutePath());
return;
}
// Ensure that the output directory path is all in tact so that
@ -289,73 +265,218 @@ public class Antlr4Mojo
outputDir.mkdirs();
}
// Now pick up all the files and process them with the Tool
//
List<List<String>> argumentSets;
try {
List<String> args = getCommandArguments();
argumentSets = processGrammarFiles(args, sourceDirectory);
} catch (InclusionScanException ie) {
log.error(ie);
throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze", ie);
}
log.debug("Output directory base will be " + outputDirectory.getAbsolutePath());
log.info("ANTLR 4: Processing source directory " + sourceDirectory.getAbsolutePath());
for (List<String> args : argumentSets) {
try {
// Create an instance of the ANTLR 4 build tool
tool = new CustomTool(args.toArray(new String[args.size()]));
} catch (Exception e) {
log.error("The attempt to create the ANTLR 4 build tool failed, see exception report for details", e);
throw new MojoFailureException("Error creating an instanceof the ANTLR tool.", e);
}
// Set working directory for ANTLR to be the base source directory
tool.inputDirectory = sourceDirectory;
tool.processGrammarsOnCommandLine();
// If any of the grammar files caused errors but did nto throw exceptions
// then we should have accumulated errors in the counts
if (tool.getNumErrors() > 0) {
throw new MojoExecutionException("ANTLR 4 caught " + tool.getNumErrors() + " build errors.");
}
}
if (project != null) {
// Tell Maven that there are some new source files underneath the output directory.
addSourceRoot(this.getOutputDirectory());
}
}
private List<String> getCommandArguments() {
List<String> args = new ArrayList<String>();
if (getOutputDirectory() != null) {
args.add("-o");
args.add(outputDir.getAbsolutePath());
args.add(outputDirectory.getAbsolutePath());
}
// Where do we want ANTLR to look for .tokens and import grammars?
//
if (getLibDirectory() != null && getLibDirectory().exists()) {
if (getLibDirectory() != null && getLibDirectory().isDirectory()) {
args.add("-lib");
args.add(libDirectory.getAbsolutePath());
}
// Next we need to set the options given to us in the pom into the
// tool instance we have created.
//
if (debug) {
args.add("-debug");
}
if (atn) {
args.add("-atn");
}
if (profile) {
args.add("-profile");
if (encoding != null && !encoding.isEmpty()) {
args.add("-encoding");
args.add(encoding);
}
if (report) {
args.add("-report");
if (listener) {
args.add("-listener");
}
if (printGrammar) {
args.add("-print");
else {
args.add("-no-listener");
}
if (visitor) {
args.add("-visitor");
}
else {
args.add("-no-visitor");
}
if (treatWarningsAsErrors) {
args.add("-Werror");
}
if (verbose_dfa) {
args.add("-Xverbose-dfa");
}
if (messageFormat != null && !"".equals(messageFormat)) {
args.add("-message-format");
args.add(messageFormat);
}
if (force_atn) {
if (forceATN) {
args.add("-Xforce-atn");
}
if (abstract_recognizer) {
args.add("-abstract");
if (options != null) {
for (Map.Entry<String, String> option : options.entrySet()) {
args.add(String.format("-D%s=%s", option.getKey(), option.getValue()));
}
}
try {
// Now pick up all the files and process them with the Tool
//
processGrammarFiles(args, sourceDirectory, outputDirectory);
} catch (InclusionScanException ie) {
log.error(ie);
throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze");
} catch (Exception e) {
getLog().error(e);
throw new MojoExecutionException(e.getMessage());
if (arguments != null) {
args.addAll(arguments);
}
// Create an instance of the ANTLR 4 build tool
//
try {
tool = new Tool(args.toArray(new String[args.size()])) {
return args;
}
/**
*
* @param sourceDirectory
* @throws org.codehaus.plexus.compiler.util.scan.InclusionScanException
*/
@NotNull
private List<List<String>> processGrammarFiles(List<String> args, File sourceDirectory) throws InclusionScanException {
// Which files under the source set should we be looking for as grammar files
SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet());
// What are the sets of includes (defaulted or otherwise).
Set<String> includes = getIncludesPatterns();
// Now, to the excludes, we need to add the imports directory
// as this is autoscanned for imported grammars and so is auto-excluded from the
// set of grammar fields we should be analyzing.
excludes.add("imports/**");
SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes);
scan.addSourceMapping(mapping);
Set<File> grammarFiles = scan.getIncludedSources(sourceDirectory, null);
if (grammarFiles.isEmpty()) {
getLog().info("No grammars to process");
return Collections.emptyList();
}
MultiMap<String, File> grammarFileByFolder = new MultiMap<String, File>();
// Iterate each grammar file we were given and add it into the tool's list of
// grammars to process.
for (File grammarFile : grammarFiles) {
getLog().debug("Grammar file '" + grammarFile.getPath() + "' detected.");
String relPathBase = findSourceSubdir(sourceDirectory, grammarFile.getPath());
String relPath = relPathBase + grammarFile.getName();
getLog().debug(" ... relative path is: " + relPath);
grammarFileByFolder.map(relPathBase, grammarFile);
}
List<List<String>> result = new ArrayList<List<String>>();
for (Map.Entry<String, List<File>> entry : grammarFileByFolder.entrySet()) {
List<String> folderArgs = new ArrayList<String>(args);
if (!folderArgs.contains("-package")) {
folderArgs.add("-package");
folderArgs.add(getPackageName(entry.getKey()));
}
for (File file : entry.getValue()) {
folderArgs.add(entry.getKey() + file.getName());
}
result.add(folderArgs);
}
return result;
}
private static String getPackageName(String relativeFolderPath) {
if (relativeFolderPath.contains("..")) {
throw new UnsupportedOperationException("Cannot handle relative paths containing '..'");
}
List<String> parts = new ArrayList<String>(Arrays.asList(relativeFolderPath.split("[/\\\\\\.]+")));
while (parts.remove("")) {
// intentionally blank
}
return Utils.join(parts.iterator(), ".");
}
public Set<String> getIncludesPatterns() {
if (includes == null || includes.isEmpty()) {
return Collections.singleton("**/*.g4");
}
return includes;
}
/**
* Given the source directory File object and the full PATH to a grammar,
* produce the path to the named grammar file in relative terms to the
* {@code sourceDirectory}. This will then allow ANTLR to produce output
* relative to the base of the output directory and reflect the input
* organization of the grammar files.
*
* @param sourceDirectory The source directory File object
* @param grammarFileName The full path to the input grammar file
* @return The path to the grammar file relative to the source directory
*/
private String findSourceSubdir(File sourceDirectory, String grammarFileName) {
String srcPath = sourceDirectory.getPath() + File.separator;
if (!grammarFileName.startsWith(srcPath)) {
throw new IllegalArgumentException("expected " + grammarFileName + " to be prefixed with " + sourceDirectory);
}
File unprefixedGrammarFileName = new File(grammarFileName.substring(srcPath.length()));
return unprefixedGrammarFileName.getParent() + File.separator;
}
private final class CustomTool extends Tool {
public CustomTool(String[] args) {
super(args);
addListener(new Antlr4ErrorLog(getLog()));
}
@Override
public void process(Grammar g, boolean gencode) {
@ -387,171 +508,9 @@ public class Antlr4Mojo
}
URI relativePath = project.getBasedir().toURI().relativize(outputFile.toURI());
getLog().info(" Writing file: " + relativePath);
getLog().debug(" Writing file: " + relativePath);
FileWriter fw = new FileWriter(outputFile);
return new BufferedWriter(fw);
}
};
tool.addListener(new Antlr4ErrorLog(log));
// we set some options directly
tool.trace = trace;
// Where do we want ANTLR to produce its output? (Base directory)
//
if (log.isDebugEnabled())
{
log.debug("Output directory base will be " + outputDirectory.getAbsolutePath());
}
// Tell ANTLR that we always want the output files to be produced in the output directory
// using the same relative path as the input file was to the input directory.
//
// tool.setForceRelativeOutput(true);
// Set working directory for ANTLR to be the base source directory
//
tool.inputDirectory = sourceDirectory;
if (!sourceDirectory.exists()) {
if (log.isInfoEnabled()) {
log.info("No ANTLR 4 grammars to compile in " + sourceDirectory.getAbsolutePath());
}
return;
} else {
if (log.isInfoEnabled()) {
log.info("ANTLR 4: Processing source directory " + sourceDirectory.getAbsolutePath());
}
}
} catch (Exception e) {
log.error("The attempt to create the ANTLR 4 build tool failed, see exception report for details", e);
throw new MojoFailureException("Jim failed you!");
}
tool.processGrammarsOnCommandLine();
// If any of the grammar files caused errors but did nto throw exceptions
// then we should have accumulated errors in the counts
//
if (tool.getNumErrors() > 0) {
throw new MojoExecutionException("ANTLR 4 caught " + tool.getNumErrors() + " build errors.");
}
// All looks good, so we need to tel Maven about the sources that
// we just created.
//
if (project != null) {
// Tell Maven that there are some new source files underneath
// the output directory.
//
addSourceRoot(this.getOutputDirectory());
}
}
/**
*
* @param sourceDirectory
* @param outputDirectory
* @throws antlr.TokenStreamException
* @throws antlr.RecognitionException
* @throws java.io.IOException
* @throws org.codehaus.plexus.compiler.util.scan.InclusionScanException
*/
private void processGrammarFiles(List<String> args, File sourceDirectory, File outputDirectory)
throws TokenStreamException, RecognitionException, IOException, InclusionScanException {
// Which files under the source set should we be looking for as grammar files
//
SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet());
// What are the sets of includes (defaulted or otherwise).
//
Set<String> includes = getIncludesPatterns();
// Now, to the excludes, we need to add the imports directory
// as this is autoscanned for importd grammars and so is auto-excluded from the
// set of gramamr fiels we shuold be analyzing.
//
excludes.add("imports/**");
SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes);
scan.addSourceMapping(mapping);
Set<?> grammarFiles = scan.getIncludedSources(sourceDirectory, null);
if (grammarFiles.isEmpty()) {
if (getLog().isInfoEnabled()) {
getLog().info("No grammars to process");
}
} else {
// Tell the ANTLR tool that we want sorted build mode
//
// tool.setMake(true);
// Iterate each grammar file we were given and add it into the tool's list of
// grammars to process.
//
for (Object grammarObject : grammarFiles) {
if (!(grammarObject instanceof File)) {
getLog().error(String.format("Expected %s from %s.getIncludedSources, found %s.",
File.class.getName(),
grammarObject != null ? grammarObject.getClass().getName() : "null"));
}
File grammarFile = (File)grammarObject;
if (getLog().isDebugEnabled()) {
getLog().debug("Grammar file '" + grammarFile.getPath() + "' detected.");
}
String relPath = findSourceSubdir(sourceDirectory, grammarFile.getPath()) + grammarFile.getName();
if (getLog().isDebugEnabled()) {
getLog().debug(" ... relative path is: " + relPath);
}
args.add(relPath);
}
}
}
public Set<String> getIncludesPatterns() {
if (includes == null || includes.isEmpty()) {
return Collections.singleton("**/*.g4");
}
return includes;
}
/**
* Given the source directory File object and the full PATH to a
* grammar, produce the path to the named grammar file in relative
* terms to the sourceDirectory. This will then allow ANTLR to
* produce output relative to the base of the output directory and
* reflect the input organization of the grammar files.
*
* @param sourceDirectory The source directory File object
* @param grammarFileName The full path to the input grammar file
* @return The path to the grammar file relative to the source directory
*/
private String findSourceSubdir(File sourceDirectory, String grammarFileName) {
String srcPath = sourceDirectory.getPath() + File.separator;
if (!grammarFileName.startsWith(srcPath)) {
throw new IllegalArgumentException("expected " + grammarFileName + " to be prefixed with " + sourceDirectory);
}
File unprefixedGrammarFileName = new File(grammarFileName.substring(srcPath.length()));
return unprefixedGrammarFileName.getParent() + File.separator;
}
}

145
pom.xml
View File

@ -1,6 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.antlr</groupId>
<artifactId>project</artifactId>
@ -8,8 +14,37 @@
<packaging>pom</packaging>
<name>ANTLR 4</name>
<description>ANTLR 4 Master Build POM</description>
<url>http://www.antlr.org</url>
<licenses>
<license>
<name>The BSD License</name>
<url>http://www.antlr.org/license.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Terence Parr</name>
<url>http://antlr.org/wiki/display/~admin/Home</url>
<roles>
<role>Project lead - ANTLR</role>
</roles>
</developer>
<developer>
<name>Sam Harwell</name>
<url>http://tunnelvisionlabs.com</url>
<roles>
<role>Developer</role>
</roles>
</developer>
</developers>
<modules>
<module>runtime/Java</module>
<module>tool</module>
@ -19,6 +54,10 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java5.home>${env.JAVA5_HOME}</java5.home>
<java6.home>${env.JAVA6_HOME}</java6.home>
<bootclasspath.compile>${java6.home}/jre/lib/rt.jar</bootclasspath.compile>
<bootclasspath.testCompile>${java6.home}/jre/lib/rt.jar</bootclasspath.testCompile>
</properties>
<issueManagement>
@ -27,16 +66,106 @@
</issueManagement>
<scm>
<url>https://github.com/antlr/antlr4</url>
<url>git://github.com/antlr/antlr4.git</url>
<connection>scm:git:git://github.com/antlr/antlr4.git</connection>
<developerConnection>scm:git:git@github.com:antlr/antlr4.git</developerConnection>
</scm>
<repositories>
<repository>
<id>antlr.snapshots</id>
<name>ANTLR Snapshots Repository</name>
<url>http://antlr.org/antlr-snapshot</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<sourceDirectory>src</sourceDirectory>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:-serial</compilerArgument>
<compilerArguments>
<bootclasspath>${bootclasspath.compile}</bootclasspath>
<Xlint/>
</compilerArguments>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:-serial</compilerArgument>
<compilerArguments>
<bootclasspath>${bootclasspath.testCompile}</bootclasspath>
<Xlint/>
</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -13,6 +13,7 @@
<artifactId>antlr4-runtime</artifactId>
<name>ANTLR 4 Runtime</name>
<description>The ANTLR 4 Runtime</description>
<dependencies>
<dependency>
@ -28,50 +29,6 @@
<sourceDirectory>src</sourceDirectory>
<resources/>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
<compilerArguments>
<Xlint/>
</compilerArguments>
<compilerArgument>-Xlint:-serial</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -45,8 +45,8 @@ public class GenHierarchy {
// If this is a directory, walk each file/dir in that directory
if (f.isDirectory()) {
String flist[] = f.list();
for(int i=0; i < flist.length; i++) {
getFilenames_(new File(f, flist[i]), files);
for (String aFlist : flist) {
getFilenames_(new File(f, aFlist), files);
}
}

View File

@ -1,6 +1,5 @@
grammar T;
s : R ;
R : 'x' EOF;
s : ID ;
ID : [a-z]+ ;

View File

@ -12,6 +12,7 @@
<artifactId>antlr4</artifactId>
<name>ANTLR 4 Tool</name>
<description>The ANTLR 4 grammar compiler.</description>
<dependencies>
<dependency>
@ -24,16 +25,19 @@
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-runtime</artifactId>
<version>3.4.1-SNAPSHOT</version>
<version>3.5.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.4</version>
<version>4.0.7-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
@ -54,10 +58,37 @@
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<createSourcesJar>true</createSourcesJar>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.antlr.v4.Tool</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr3-maven-plugin</artifactId>
<version>3.4</version>
<version>3.5.1-SNAPSHOT</version>
<configuration>
<sourceDirectory>src</sourceDirectory>
<verbose>true</verbose>
@ -71,43 +102,6 @@
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>

View File

@ -118,11 +118,6 @@ public class Tool {
public File inputDirectory;
public String outputDirectory;
public String libDirectory;
public boolean report = false;
public boolean printGrammar = false;
public boolean debug = false;
public boolean profile = false;
public boolean trace = false;
public boolean generate_ATN_dot = false;
public String grammarEncoding = null; // use default locale's encoding
public String msgFormat = "antlr";
@ -141,12 +136,6 @@ public class Tool {
public static Option[] optionDefs = {
new Option("outputDirectory", "-o", OptionArgType.STRING, "specify output directory where all output is generated"),
new Option("libDirectory", "-lib", OptionArgType.STRING, "specify location of grammars, tokens files"),
/*
new Option("report", "-report", "print out a report about the grammar(s) processed"),
new Option("printGrammar", "-print", "print out the grammar without actions"),
new Option("debug", "-debug", "generate a parser that emits debugging events"),
new Option("profile", "-profile", "generate a parser that computes profiling information"),
*/
new Option("generate_ATN_dot", "-atn", "generate rule augmented transition network diagrams"),
new Option("grammarEncoding", "-encoding", OptionArgType.STRING, "specify grammar file encoding; e.g., euc-jp"),
new Option("msgFormat", "-message-format", OptionArgType.STRING, "specify output style for messages in antlr, gnu, vs2005"),