packages: antlr3/ANTLR3.java (NEW) - ant task for antlrr3 - from http://ant...

pawelz pawelz at pld-linux.org
Tue Oct 13 12:29:03 CEST 2009


Author: pawelz                       Date: Tue Oct 13 10:29:03 2009 GMT
Module: packages                      Tag: HEAD
---- Log message:
- ant task for antlrr3
- from http://antlr.org/share/1169924912745/antlr3-task.zip

---- Files affected:
packages/antlr3:
   ANTLR3.java (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/antlr3/ANTLR3.java
diff -u /dev/null packages/antlr3/ANTLR3.java:1.1
--- /dev/null	Tue Oct 13 12:29:03 2009
+++ packages/antlr3/ANTLR3.java	Tue Oct 13 12:28:58 2009
@@ -0,0 +1,776 @@
+/*
+ * Copyright  2000-2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ *
+ *  2006-12-29: Modified to work for antlr3 by Jürgen Pfundt
+ *  2007-01-04: Some minor correction after checking code with findBugs tool
+ *  2007-02-10: Adapted the grammar type recognition to the changed naming
+ *              conventions for Tree Parser
+ *  2007-10-17: Options "trace", "traceLexer", "traceParser" and "glib" emit
+ *              warnings when being used.
+ *              Added recognition of "parser grammar T".
+ *              Added options "nocollapse", "noprune".
+ *              ANTLR option "depend" is being used to resolve build dependencies.
+ *  2007-11-15: Embedded Classpath statement had not been observed
+ *              with option depend="true" (Reported by Mats Behre)
+ *  2008-03-31: Support the option conversiontimeout. (Jim Idle)
+ *  2007-12-31: With option "depend=true" proceed even if first pass failed so
+ *              that ANTLR can spit out its errors
+ *  2008-08-09: Inspecting environment variable ANTLR_HOME to detect and add
+ *              antlr- and stringtemplate libraries to the classpath
+ *  2008-08-09: Removed routine checkGenerateFile. It got feeble with the
+ *              introduction of composed grammars, e.g. "import T.g" and after
+ *              a short struggle it started it's journey to /dev/null.
+ *              From now one it is always antlr itself via the depend option
+ *              which decides about dependecies
+ *  2008-08-19: Dependency check for composed grammars added.
+ *              Might need some further improvements.
+ */
+package org.apache.tools.ant.antlr;
+
+import java.util.regex.*;
+import java.io.*;
+import java.util.Map;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+import org.apache.tools.ant.taskdefs.Redirector;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.LoaderUtils;
+import org.apache.tools.ant.util.TeeOutputStream;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ *  Invokes the ANTLR3 Translator generator on a grammar file.
+ *
+ */
+public class ANTLR3 extends Task {
+
+    private CommandlineJava commandline = new CommandlineJava();
+    /** the file to process */
+    private File target = null;
+    /** where to output the result */
+    private File outputDirectory = null;
+    /** location of token files */
+    private File libDirectory = null;
+    /** an optional super grammar file */
+    private File superGrammar;
+    /** depend */
+    private boolean depend = false;
+    /** fork */
+    private boolean fork;
+    /** name of output style for messages */
+    private String messageFormatName;
+    /** optional flag to print out a diagnostic file */
+    private boolean diagnostic;
+    /** optional flag to add methods */
+    private boolean trace;
+    /** optional flag to add trace methods to the parser only */
+    private boolean traceParser;
+    /** optional flag to add trace methods to the lexer only */
+    private boolean traceLexer;
+    /** working directory */
+    private File workingdir = null;
+    /** captures ANTLR's output */
+    private ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    /** The debug attribute */
+    private boolean debug;
+    /** The report attribute */
+    private boolean report;
+    /** The print attribute */
+    private boolean print;
+    /** The profile attribute */
+    private boolean profile;
+    /** The nfa attribute */
+    private boolean nfa;
+    /** The dfa attribute */
+    private boolean dfa;
+    /** multi threaded analysis */
+    private boolean multiThreaded;
+    /** collapse incident edges into DFA states */
+    private boolean nocollapse;
+    /** test lookahead against EBNF block exit branches */
+    private boolean noprune;
+    /** put tags at start/stop of all templates in output */
+    private boolean dbgST;
+    /** print AST */
+    private boolean grammarTree;
+    /** Instance of a utility class to use for file operations. */
+    private FileUtils fileUtils;
+    /**
+     * Whether to override the default conversion timeout with -Xconversiontimeout nnnn
+     */
+    private String conversiontimeout;
+
+    public ANTLR3() {
+        commandline.setVm(JavaEnvUtils.getJreExecutable("java"));
+        commandline.setClassname("org.antlr.Tool");
+        fileUtils = FileUtils.getFileUtils();
+    }
+
+    /**
+     * The grammar file to process.
+     */
+    public void setTarget(File targetFile) {
+        log("Setting target to: " + targetFile.toString(), Project.MSG_VERBOSE);
+        this.target = targetFile;
+    }
+
+    /**
+     * The directory to write the generated files to.
+     */
+    public void setOutputdirectory(File outputDirectoryFile) {
+        log("Setting output directory to: " + outputDirectoryFile.toString(), Project.MSG_VERBOSE);
+        this.outputDirectory = outputDirectoryFile;
+    }
+
+    /**
+     * The directory to write the generated files to.
+     */
+    public File getOutputdirectory() {
+        return outputDirectory;
+    }
+
+    /**
+     * The token files output directory.
+     */
+    public void setLibdirectory(File libDirectoryFile) {
+        log("Setting lib directory to: " + libDirectoryFile.toString(), Project.MSG_VERBOSE);
+        this.libDirectory = libDirectoryFile;
+    }
+
+    /**
+     * The output style for messages.
+     */
+    public void setMessageformat(String name) {
+        log("Setting message-format to: " + name, Project.MSG_VERBOSE);
+        this.messageFormatName = name;
+    }
+
+    /**
+     * Sets an optional super grammar file
+     * @deprecated
+     */
+    public void setGlib(File superGrammarFile) {
+        this.superGrammar = superGrammarFile;
+    }
+
+    /**
+     * Sets a flag to enable ParseView debugging
+     */
+    public void setDebug(boolean enable) {
+        this.debug = enable;
+    }
+
+    /**
+     * Sets a flag to enable report statistics
+     */
+    public void setReport(boolean enable) {
+        this.report = enable;
+    }
+
+    /**
+     * Sets a flag to print out the grammar without actions
+     */
+    public void setPrint(boolean enable) {
+        this.print = enable;
+    }
+
+    /**
+     * Sets a flag to enable profiling
+     */
+    public void setProfile(boolean enable) {
+        this.profile = enable;
+    }
+
+    /**
+     * Sets a flag to enable nfa generation
+     */
+    public void setNfa(boolean enable) {
+        this.nfa = enable;
+    }
+
+    /**
+     * Sets a flag to enable nfa generation
+     */
+    public void setDfa(boolean enable) {
+        this.dfa = enable;
+    }
+
+    /**
+     * Run the analysis multithreaded
+     * @param enable
+     */
+    public void setMultithreaded(boolean enable) {
+        multiThreaded = enable;
+    }
+
+    /**
+     * collapse incident edges into DFA states
+     * @param enable
+     */
+    public void setNocollapse(boolean enable) {
+        nocollapse = enable;
+    }
+
+    /**
+     * test lookahead against EBNF block exit branches
+     * @param enable
+     */
+    public void setNoprune(boolean enable) {
+        noprune = enable;
+    }
+
+    /**
+     * test lookahead against EBNF block exit branches
+     * @param enable
+     */
+    public void setDbgST(boolean enable) {
+        dbgST = enable;
+    }
+
+    /**
+     * override the default conversion timeout with -Xconversiontimeout nnnn
+     * @param conversiontimeoutString
+     */
+    public void setConversiontimeout(String conversiontimeoutString) {
+        log("Setting conversiontimeout to: " + conversiontimeoutString, Project.MSG_VERBOSE);
+        try {
+            int timeout = Integer.valueOf(conversiontimeoutString);
+            this.conversiontimeout = conversiontimeoutString;
+        } catch (NumberFormatException e) {
+            log("Option ConversionTimeOut ignored due to illegal value: '" + conversiontimeoutString + "'", Project.MSG_ERR);
+        }
+    }
+
+    /**
+     * Set a flag to enable printing of the grammar tree
+     */
+    public void setGrammartree(boolean enable) {
+        grammarTree = enable;
+    }
+
+    /**
+     * Set a flag to enable dependency checking by ANTLR itself
+     * The depend option is always used implicitely inside the antlr3 task
+     * @deprecated
+     */
+    public void setDepend(boolean s) {
+        this.depend = s;
+    }
+
+    /**
+     * Sets a flag to emit diagnostic text
+     */
+    public void setDiagnostic(boolean enable) {
+        diagnostic = enable;
+    }
+
+    /**
+     * If true, enables all tracing.
+     * @deprecated
+     */
+    public void setTrace(boolean enable) {
+        trace = enable;
+    }
+
+    /**
+     * If true, enables parser tracing.
+     * @deprecated
+     */
+    public void setTraceParser(boolean enable) {
+        traceParser = enable;
+    }
+
+    /**
+     * If true, enables lexer tracing.
+     * @deprecated
+     */
+    public void setTraceLexer(boolean enable) {
+        traceLexer = enable;
+    }
+
+    // we are forced to fork ANTLR since there is a call
+    // to System.exit() and there is nothing we can do
+    // right now to avoid this. :-( (SBa)
+    // I'm not removing this method to keep backward compatibility
+    /**
+     * @ant.attribute ignore="true"
+     */
+    public void setFork(boolean s) {
+        this.fork = s;
+    }
+
+    /**
+     * The working directory of the process
+     */
+    public void setDir(File d) {
+        this.workingdir = d;
+    }
+
+    /**
+     * Adds a classpath to be set
+     * because a directory might be given for Antlr debug.
+     */
+    public Path createClasspath() {
+        return commandline.createClasspath(getProject()).createPath();
+    }
+
+    /**
+     * Adds a new JVM argument.
+     * @return  create a new JVM argument so that any argument can be passed to the JVM.
+     * @see #setFork(boolean)
+     */
+    public Commandline.Argument createJvmarg() {
+        return commandline.createVmArgument();
+    }
+
+    /**
+     * Adds the jars or directories containing Antlr and associates.
+     * This should make the forked JVM work without having to
+     * specify it directly.
+     */
+    @Override
+    public void init() throws BuildException {
+        /* Inquire environment variables */
+        Map<String, String> variables = System.getenv();
+        /* Get value for key "ANTLR_HOME" which should hopefully point to
+         * the directory where the current version of antlr3 is installed */
+        String antlrHome = variables.get("ANTLR_HOME");
+        if (antlrHome != null) {
+            /* Environment variable ANTLR_HOME has been defined.
+             * Now add all antlr and stringtemplate libraries to the
+             * classpath */
+            addAntlrJarsToClasspath(antlrHome + "/lib");
+        }
+        addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class", "AntLR2");
+        addClasspathEntry("/org/antlr/tool/ANTLRParser.class", "AntLR3");
+        addClasspathEntry("/org/antlr/stringtemplate/StringTemplate.class", "Stringtemplate");
+
+
+    }
+
+    /**
+     * Search for the given resource and add the directory or archive
+     * that contains it to the classpath.
+     *
+     * <p>Doesn't work for archives in JDK 1.1 as the URL returned by
+     * getResource doesn't contain the name of the archive.</p>
+     */
+    protected void addClasspathEntry(String resource, String msg) {
+        /*
+         * pre Ant 1.6 this method used to call getClass().getResource
+         * while Ant 1.6 will call ClassLoader.getResource().
+         *
+         * The difference is that Class.getResource expects a leading
+         * slash for "absolute" resources and will strip it before
+         * delegating to ClassLoader.getResource - so we now have to
+         * emulate Class's behavior.
+         */
+        if (resource.startsWith("/")) {
+            resource = resource.substring(1);
+        } else {
+            resource = "org/apache/tools/ant/taskdefs/optional/" + resource;
+        }
+
+        File f = LoaderUtils.getResourceSource(getClass().getClassLoader(), resource);
+        if (f != null) {
+            log("Found via classpath: " + f.getAbsolutePath(), Project.MSG_VERBOSE);
+            createClasspath().setLocation(f);
+        } else {
+            log("Couldn\'t find resource " + resource + " for library " + msg + " in external classpath", Project.MSG_VERBOSE);
+        }
+    }
+
+    /**
+     * If the environment variable ANTLR_HOME is defined and points
+     * to the installation directory of antlr3 then look for all antlr-*.jar and
+     * stringtemplate-*.jar files in the lib directory and add them
+     * to the classpath.
+     * This feature should make working with eclipse or netbeans projects a
+     * little bit easier. As wildcards are being used for the version part
+     * of the jar-archives it makes the task independent of
+     * new releases. Just let ANTLR_HOME point to the new installation
+     * directory.
+     */
+    private void addAntlrJarsToClasspath(String antlrLibDir) {
+        String[] includes = {"antlr-*.jar", "stringtemplate-*.jar"};
+
+        DirectoryScanner ds = new DirectoryScanner();
+        ds.setIncludes(includes);
+        ds.setBasedir(new File(antlrLibDir));
+        ds.setCaseSensitive(true);
+        ds.scan();
+
+        String separator = System.getProperty("file.separator");
+        String[] files = ds.getIncludedFiles();
+        for (String file : files) {
+            File f = new File(antlrLibDir + separator + file);
+            log("Found via ANTLR_HOME: " + f.getAbsolutePath(), Project.MSG_VERBOSE);
+            createClasspath().setLocation(f);
+        }
+    }
+
+    @Override
+    public void execute() throws BuildException {
+
+        validateAttributes();
+
+        // Use ANTLR itself to resolve dependencies and decide whether
+        // to invoke ANTLR for compilation
+        if (dependencyCheck()) {
+            populateAttributes();
+            commandline.createArgument().setValue(target.toString());
+
+            log(commandline.describeCommand(), Project.MSG_VERBOSE);
+            int err = 0;
+            try {
+                err = run(commandline.getCommandline(), new LogOutputStream(this, Project.MSG_INFO), new LogOutputStream(this, Project.MSG_WARN));
+            } catch (IOException e) {
+                throw new BuildException(e, getLocation());
+            } finally {
+                try {
+                    bos.close();
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+
+            if (err != 0) {
+                throw new BuildException("ANTLR returned: " + err, getLocation());
+            } else {
+                Pattern p = Pattern.compile("error\\([0-9]+\\):");
+                Matcher m = p.matcher(bos.toString());
+                if (m.find()) {
+                    throw new BuildException("ANTLR signaled an error.", getLocation());
+                }
+            }
+        } else {
+            try {
+                log("All dependencies of grammar file \'" + target.getCanonicalPath() + "\' are up to date.", Project.MSG_VERBOSE);
+            } catch (IOException ex) {
+                log("All dependencies of grammar file \'" + target.toString() + "\' are up to date.", Project.MSG_VERBOSE);
+            }
+        }
+    }
+
+    /**
+     * A refactored method for populating all the command line arguments based
+     * on the user-specified attributes.
+     */
+    private void populateAttributes() {
+
+        commandline.createArgument().setValue("-o");
+        commandline.createArgument().setValue(outputDirectory.toString());
+
+        commandline.createArgument().setValue("-lib");
+        commandline.createArgument().setValue(libDirectory.toString());
+
+        if (superGrammar != null) {
+            log("Option 'glib' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
+        }
+
+        if (diagnostic) {
+            commandline.createArgument().setValue("-diagnostic");
+        }
+        if (depend) {
+            log("Option 'depend' is implicitely always used by ANTLR v3. Option can safely be omitted!", Project.MSG_WARN);
+        }
+        if (trace) {
+            log("Option 'trace' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
+        }
+        if (traceParser) {
+            log("Option 'traceParser' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
+        }
+        if (traceLexer) {
+            log("Option 'traceLexer' is not supported by ANTLR v3. Option ignored!", Project.MSG_WARN);
+        }
+        if (debug) {
+            commandline.createArgument().setValue("-debug");
+        }
+        if (report) {
+            commandline.createArgument().setValue("-report");
+        }
+        if (print) {
+            commandline.createArgument().setValue("-print");
+        }
+        if (profile) {
+            commandline.createArgument().setValue("-profile");
+        }
+        if (messageFormatName != null) {
+            commandline.createArgument().setValue("-message-format");
+            commandline.createArgument().setValue(messageFormatName);
+        }
+        if (nfa) {
+            commandline.createArgument().setValue("-nfa");
+        }
+        if (dfa) {
+            commandline.createArgument().setValue("-dfa");
+        }
+        if (multiThreaded) {
+            commandline.createArgument().setValue("-Xmultithreaded");
+        }
+        if (nocollapse) {
+            commandline.createArgument().setValue("-Xnocollapse");
+        }
+        if (noprune) {
+            commandline.createArgument().setValue("-Xnoprune");
+        }
+        if (dbgST) {
+            commandline.createArgument().setValue("-XdbgST");
+        }
+        if (conversiontimeout != null) {
+            commandline.createArgument().setValue("-Xconversiontimeout");
+            commandline.createArgument().setValue(conversiontimeout);
+        }
+        if (grammarTree) {
+            commandline.createArgument().setValue("-Xgrtree");
+        }
+    }
+
+    private void validateAttributes() throws BuildException {
+
+        if (target == null) {
+            throw new BuildException("No target grammar, lexer grammar or tree parser specified!");
+        } else if (!target.isFile()) {
+            throw new BuildException("Target: " + target + " is not a file!");
+        }
+
+        // if no output directory is specified, use the target's directory
+        if (outputDirectory == null) {
+            setOutputdirectory(new File(target.getParent()));
+        }
+
+        if (!outputDirectory.isDirectory()) {
+            throw new BuildException("Invalid output directory: " + outputDirectory);
+        }
+
+        if (workingdir != null && !workingdir.isDirectory()) {
+            throw new BuildException("Invalid working directory: " + workingdir);
+        }
+
+        // if no libDirectory is specified, use the target's directory
+        if (libDirectory == null) {
+            setLibdirectory(new File(target.getParent()));
+        }
+
+        if (!libDirectory.isDirectory()) {
+            throw new BuildException("Invalid lib directory: " + libDirectory);
+        }
+    }
+
+    private boolean dependencyCheck() throws BuildException {
+        // using "antlr -o <OutputDirectory> -lib <LibDirectory> -depend <T>"
+        // to get the list of dependencies
+        CommandlineJava cmdline;
+        try {
+            cmdline = (CommandlineJava) commandline.clone();
+        } catch (java.lang.CloneNotSupportedException e) {
+            throw new BuildException("Clone of commandline failed: " + e);
+        }
+
+        cmdline.createArgument().setValue("-depend");
+        cmdline.createArgument().setValue("-o");
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list