| /* |
| * [The "BSD license"] |
| * Copyright (c) 2010 Terence Parr |
| * All rights reserved. |
| * |
| * 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. |
| */ |
| package org.antlr; |
| |
| import org.antlr.analysis.*; |
| import org.antlr.codegen.CodeGenerator; |
| import org.antlr.misc.Graph; |
| import org.antlr.runtime.misc.Stats; |
| import org.antlr.tool.*; |
| import org.stringtemplate.v4.STGroup; |
| |
| import java.io.*; |
| import java.util.*; |
| |
| /** The main ANTLR entry point. Read a grammar and generate a parser. */ |
| public class Tool { |
| |
| public final Properties antlrSettings = new Properties(); |
| public String VERSION = "3.4"; |
| //public static final String VERSION = "${project.version}"; |
| public static final String UNINITIALIZED_DIR = "<unset-dir>"; |
| private List<String> grammarFileNames = new ArrayList<String>(); |
| private boolean generate_NFA_dot = false; |
| private boolean generate_DFA_dot = false; |
| private String outputDirectory = "."; |
| private boolean haveOutputDir = false; |
| private String inputDirectory = null; |
| private String parentGrammarDirectory; |
| private String grammarOutputDirectory; |
| private boolean haveInputDir = false; |
| private String libDirectory = "."; |
| private boolean debug = false; |
| private boolean trace = false; |
| private boolean profile = false; |
| private boolean report = false; |
| private boolean printGrammar = false; |
| private boolean depend = false; |
| private boolean forceAllFilesToOutputDir = false; |
| private boolean forceRelativeOutput = false; |
| protected boolean deleteTempLexer = true; |
| private boolean verbose = false; |
| /** Don't process grammar file if generated files are newer than grammar */ |
| private boolean make = false; |
| private boolean showBanner = true; |
| private static boolean exitNow = false; |
| private static boolean return_dont_exit = false; |
| |
| |
| public String forcedLanguageOption; // -language L on command line |
| |
| // The internal options are for my use on the command line during dev |
| // |
| public static boolean internalOption_PrintGrammarTree = false; |
| public static boolean internalOption_PrintDFA = false; |
| public static boolean internalOption_ShowNFAConfigsInDFA = false; |
| public static boolean internalOption_watchNFAConversion = false; |
| |
| /** |
| * A list of dependency generators that are accumulated aaaas (and if) the |
| * tool is required to sort the provided grammars into build dependency order. |
| protected Map<String, BuildDependencyGenerator> buildDependencyGenerators; |
| */ |
| |
| public static void main(String[] args) { |
| Tool antlr = new Tool(args); |
| |
| if (!exitNow) { |
| antlr.process(); |
| if ( return_dont_exit ) return; |
| if (ErrorManager.getNumErrors() > 0) { |
| System.exit(1); |
| } |
| System.exit(0); |
| } |
| } |
| |
| /** |
| * Load the properties file org/antlr/antlr.properties and populate any |
| * variables that must be initialized from it, such as the version of ANTLR. |
| */ |
| private void loadResources() { |
| InputStream in = null; |
| in = this.getClass().getResourceAsStream("antlr.properties"); |
| |
| // If we found the resource, then load it, otherwise revert to the |
| // defaults. |
| // |
| if (in != null) { |
| try { |
| // Load the resources into the map |
| // |
| antlrSettings.load(in); |
| |
| // Set any variables that we need to populate from the resources |
| // |
| // VERSION = antlrSettings.getProperty("antlr.version"); |
| } catch (Exception e) { |
| // Do nothing, just leave the defaults in place |
| } |
| } |
| } |
| |
| public Tool() { |
| loadResources(); |
| } |
| |
| public Tool(String[] args) { |
| loadResources(); |
| |
| // Set all the options and pick up all the named grammar files |
| processArgs(args); |
| } |
| |
| public void processArgs(String[] args) { |
| |
| if (isVerbose()) { |
| ErrorManager.info("ANTLR Parser Generator Version " + VERSION); |
| showBanner = false; |
| } |
| |
| if (args == null || args.length == 0) { |
| help(); |
| return; |
| } |
| for (int i = 0; i < args.length; i++) { |
| if (args[i].equals("-o") || args[i].equals("-fo")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing output directory with -fo/-o option; ignoring"); |
| } |
| else { |
| if (args[i].equals("-fo")) { // force output into dir |
| setForceAllFilesToOutputDir(true); |
| } |
| i++; |
| outputDirectory = args[i]; |
| if (outputDirectory.endsWith("/") || |
| outputDirectory.endsWith("\\")) { |
| outputDirectory = |
| outputDirectory.substring(0, getOutputDirectory().length() - 1); |
| } |
| File outDir = new File(outputDirectory); |
| haveOutputDir = true; |
| if (outDir.exists() && !outDir.isDirectory()) { |
| ErrorManager.error(ErrorManager.MSG_OUTPUT_DIR_IS_FILE, outputDirectory); |
| setLibDirectory("."); |
| } |
| } |
| } |
| else if (args[i].equals("-lib")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing library directory with -lib option; ignoring"); |
| } |
| else { |
| i++; |
| setLibDirectory(args[i]); |
| if (getLibraryDirectory().endsWith("/") || |
| getLibraryDirectory().endsWith("\\")) { |
| setLibDirectory(getLibraryDirectory().substring(0, getLibraryDirectory().length() - 1)); |
| } |
| File outDir = new File(getLibraryDirectory()); |
| if (!outDir.exists()) { |
| ErrorManager.error(ErrorManager.MSG_DIR_NOT_FOUND, getLibraryDirectory()); |
| setLibDirectory("."); |
| } |
| } |
| } |
| else if (args[i].equals("-language")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing language name; ignoring"); |
| } |
| else { |
| i++; |
| forcedLanguageOption = args[i]; |
| } |
| } |
| else if (args[i].equals("-nfa")) { |
| setGenerate_NFA_dot(true); |
| } |
| else if (args[i].equals("-dfa")) { |
| setGenerate_DFA_dot(true); |
| } |
| else if (args[i].equals("-debug")) { |
| setDebug(true); |
| } |
| else if (args[i].equals("-trace")) { |
| setTrace(true); |
| } |
| else if (args[i].equals("-report")) { |
| setReport(true); |
| } |
| else if (args[i].equals("-profile")) { |
| setProfile(true); |
| } |
| else if (args[i].equals("-print")) { |
| setPrintGrammar(true); |
| } |
| else if (args[i].equals("-depend")) { |
| setDepend(true); |
| } |
| else if (args[i].equals("-verbose")) { |
| setVerbose(true); |
| } |
| else if (args[i].equals("-version")) { |
| version(); |
| exitNow = true; |
| } |
| else if (args[i].equals("-make")) { |
| setMake(true); |
| } |
| else if (args[i].equals("-message-format")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing output format with -message-format option; using default"); |
| } |
| else { |
| i++; |
| ErrorManager.setFormat(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xgrtree")) { |
| internalOption_PrintGrammarTree = true; // print grammar tree |
| } |
| else if (args[i].equals("-Xdfa")) { |
| internalOption_PrintDFA = true; |
| } |
| else if (args[i].equals("-Xnoprune")) { |
| DFAOptimizer.PRUNE_EBNF_EXIT_BRANCHES = false; |
| } |
| else if (args[i].equals("-Xnocollapse")) { |
| DFAOptimizer.COLLAPSE_ALL_PARALLEL_EDGES = false; |
| } |
| else if (args[i].equals("-Xdbgconversion")) { |
| NFAToDFAConverter.debug = true; |
| } |
| else if (args[i].equals("-Xmultithreaded")) { |
| NFAToDFAConverter.SINGLE_THREADED_NFA_CONVERSION = false; |
| } |
| else if (args[i].equals("-Xnomergestopstates")) { |
| DFAOptimizer.MERGE_STOP_STATES = false; |
| } |
| else if (args[i].equals("-Xdfaverbose")) { |
| internalOption_ShowNFAConfigsInDFA = true; |
| } |
| else if (args[i].equals("-Xwatchconversion")) { |
| internalOption_watchNFAConversion = true; |
| } |
| else if (args[i].equals("-XdbgST")) { |
| CodeGenerator.LAUNCH_ST_INSPECTOR = true; |
| STGroup.trackCreationEvents = true; |
| return_dont_exit = true; |
| } |
| else if (args[i].equals("-Xmaxinlinedfastates")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing max inline dfa states -Xmaxinlinedfastates option; ignoring"); |
| } |
| else { |
| i++; |
| CodeGenerator.MAX_ACYCLIC_DFA_STATES_INLINE = Integer.parseInt(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xmaxswitchcaselabels")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing max switch case labels -Xmaxswitchcaselabels option; ignoring"); |
| } |
| else { |
| i++; |
| CodeGenerator.MAX_SWITCH_CASE_LABELS = Integer.parseInt(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xminswitchalts")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing min switch alternatives -Xminswitchalts option; ignoring"); |
| } |
| else { |
| i++; |
| CodeGenerator.MIN_SWITCH_ALTS = Integer.parseInt(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xm")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing max recursion with -Xm option; ignoring"); |
| } |
| else { |
| i++; |
| NFAContext.MAX_SAME_RULE_INVOCATIONS_PER_NFA_CONFIG_STACK = Integer.parseInt(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xmaxdfaedges")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing max number of edges with -Xmaxdfaedges option; ignoring"); |
| } |
| else { |
| i++; |
| DFA.MAX_STATE_TRANSITIONS_FOR_TABLE = Integer.parseInt(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xconversiontimeout")) { |
| if (i + 1 >= args.length) { |
| System.err.println("missing max time in ms -Xconversiontimeout option; ignoring"); |
| } |
| else { |
| i++; |
| DFA.MAX_TIME_PER_DFA_CREATION = Integer.parseInt(args[i]); |
| } |
| } |
| else if (args[i].equals("-Xnfastates")) { |
| DecisionProbe.verbose = true; |
| } |
| else if (args[i].equals("-Xsavelexer")) { |
| deleteTempLexer = false; |
| } |
| else if (args[i].equals("-X")) { |
| Xhelp(); |
| } |
| else { |
| if (args[i].charAt(0) != '-') { |
| // Must be the grammar file |
| addGrammarFile(args[i]); |
| } |
| } |
| } |
| } |
| |
| /* |
| protected void checkForInvalidArguments(String[] args, BitSet cmdLineArgValid) { |
| // check for invalid command line args |
| for (int a = 0; a < args.length; a++) { |
| if (!cmdLineArgValid.member(a)) { |
| System.err.println("invalid command-line argument: " + args[a] + "; ignored"); |
| } |
| } |
| } |
| */ |
| |
| /** |
| * Checks to see if the list of outputFiles all exist, and have |
| * last-modified timestamps which are later than the last-modified |
| * timestamp of all the grammar files involved in build the output |
| * (imports must be checked). If these conditions hold, the method |
| * returns false, otherwise, it returns true. |
| * |
| * @param grammarFileName The grammar file we are checking |
| */ |
| public boolean buildRequired(String grammarFileName) |
| throws IOException |
| { |
| BuildDependencyGenerator bd = |
| new BuildDependencyGenerator(this, grammarFileName); |
| |
| List<File> outputFiles = bd.getGeneratedFileList(); |
| List<File> inputFiles = bd.getDependenciesFileList(); |
| // Note that input directory must be set to use buildRequired |
| File grammarFile; |
| if (haveInputDir) { |
| grammarFile = new File(inputDirectory, grammarFileName); |
| } |
| else { |
| grammarFile = new File(grammarFileName); |
| } |
| long grammarLastModified = grammarFile.lastModified(); |
| for (File outputFile : outputFiles) { |
| if (!outputFile.exists() || grammarLastModified > outputFile.lastModified()) { |
| // One of the output files does not exist or is out of date, so we must build it |
| return true; |
| } |
| // Check all of the imported grammars and see if any of these are younger |
| // than any of the output files. |
| if (inputFiles != null) { |
| for (File inputFile : inputFiles) { |
| |
| if (inputFile.lastModified() > outputFile.lastModified()) { |
| // One of the imported grammar files has been updated so we must build |
| return true; |
| } |
| } |
| } |
| } |
| if (isVerbose()) { |
| System.out.println("Grammar " + grammarFile + " is up to date - build skipped"); |
| } |
| return false; |
| } |
| |
| public void process() { |
| boolean exceptionWhenWritingLexerFile = false; |
| String lexerGrammarFileName = null; // necessary at this scope to have access in the catch below |
| |
| // Have to be tricky here when Maven or build tools call in and must new Tool() |
| // before setting options. The banner won't display that way! |
| if (isVerbose() && showBanner) { |
| ErrorManager.info("ANTLR Parser Generator Version " + VERSION); |
| showBanner = false; |
| } |
| |
| try { |
| sortGrammarFiles(); // update grammarFileNames |
| } |
| catch (Exception e) { |
| ErrorManager.error(ErrorManager.MSG_INTERNAL_ERROR,e); |
| } |
| catch (Error e) { |
| ErrorManager.error(ErrorManager.MSG_INTERNAL_ERROR, e); |
| } |
| |
| for (String grammarFileName : grammarFileNames) { |
| // If we are in make mode (to support build tools like Maven) and the |
| // file is already up to date, then we do not build it (and in verbose mode |
| // we will say so). |
| if (make) { |
| try { |
| if ( !buildRequired(grammarFileName) ) continue; |
| } |
| catch (Exception e) { |
| ErrorManager.error(ErrorManager.MSG_INTERNAL_ERROR,e); |
| } |
| } |
| |
| if (isVerbose() && !isDepend()) { |
| System.out.println(grammarFileName); |
| } |
| try { |
| if (isDepend()) { |
| BuildDependencyGenerator dep = |
| new BuildDependencyGenerator(this, grammarFileName); |
| /* |
| List outputFiles = dep.getGeneratedFileList(); |
| List dependents = dep.getDependenciesFileList(); |
| System.out.println("output: "+outputFiles); |
| System.out.println("dependents: "+dependents); |
| */ |
| System.out.println(dep.getDependencies().render()); |
| continue; |
| } |
| |
| Grammar rootGrammar = getRootGrammar(grammarFileName); |
| // we now have all grammars read in as ASTs |
| // (i.e., root and all delegates) |
| rootGrammar.composite.assignTokenTypes(); |
| //rootGrammar.composite.translateLeftRecursiveRules(); |
| rootGrammar.addRulesForSyntacticPredicates(); |
| rootGrammar.composite.defineGrammarSymbols(); |
| rootGrammar.composite.createNFAs(); |
| |
| generateRecognizer(rootGrammar); |
| |
| if (isPrintGrammar()) { |
| rootGrammar.printGrammar(System.out); |
| } |
| |
| if (isReport()) { |
| GrammarReport2 greport = new GrammarReport2(rootGrammar); |
| System.out.print(greport.toString()); |
| // GrammarReport greport = new GrammarReport(rootGrammar); |
| // System.out.println(greport.toString()); |
| // // print out a backtracking report too (that is not encoded into log) |
| // System.out.println(greport.getBacktrackingReport()); |
| } |
| if (isProfile()) { |
| GrammarReport greport = new GrammarReport(rootGrammar); |
| Stats.writeReport(GrammarReport.GRAMMAR_STATS_FILENAME, |
| greport.toNotifyString()); |
| } |
| |
| // now handle the lexer if one was created for a merged spec |
| String lexerGrammarStr = rootGrammar.getLexerGrammar(); |
| //System.out.println("lexer rootGrammar:\n"+lexerGrammarStr); |
| if (rootGrammar.type == Grammar.COMBINED && lexerGrammarStr != null) { |
| lexerGrammarFileName = rootGrammar.getImplicitlyGeneratedLexerFileName(); |
| try { |
| Writer w = getOutputFile(rootGrammar, lexerGrammarFileName); |
| w.write(lexerGrammarStr); |
| w.close(); |
| } |
| catch (IOException e) { |
| // emit different error message when creating the implicit lexer fails |
| // due to write permission error |
| exceptionWhenWritingLexerFile = true; |
| throw e; |
| } |
| try { |
| StringReader sr = new StringReader(lexerGrammarStr); |
| Grammar lexerGrammar = new Grammar(this); |
| lexerGrammar.composite.watchNFAConversion = internalOption_watchNFAConversion; |
| lexerGrammar.implicitLexer = true; |
| //lexerGrammar.setTool(this); |
| File lexerGrammarFullFile = |
| new File(getFileDirectory(lexerGrammarFileName), lexerGrammarFileName); |
| lexerGrammar.setFileName(lexerGrammarFullFile.toString()); |
| |
| lexerGrammar.importTokenVocabulary(rootGrammar); |
| lexerGrammar.parseAndBuildAST(sr); |
| |
| sr.close(); |
| |
| lexerGrammar.composite.assignTokenTypes(); |
| lexerGrammar.addRulesForSyntacticPredicates(); |
| lexerGrammar.composite.defineGrammarSymbols(); |
| lexerGrammar.composite.createNFAs(); |
| |
| generateRecognizer(lexerGrammar); |
| } |
| finally { |
| // make sure we clean up |
| if (deleteTempLexer) { |
| File outputDir = getOutputDirectory(lexerGrammarFileName); |
| File outputFile = new File(outputDir, lexerGrammarFileName); |
| outputFile.delete(); |
| } |
| } |
| } |
| } |
| catch (IOException e) { |
| if (exceptionWhenWritingLexerFile) { |
| ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, e); |
| } |
| else { |
| ErrorManager.error(ErrorManager.MSG_CANNOT_OPEN_FILE, |
| grammarFileName); |
| } |
| } |
| catch (Exception e) { |
| ErrorManager.error(ErrorManager.MSG_INTERNAL_ERROR, grammarFileName, e); |
| } |
| /* |
| finally { |
| System.out.println("creates="+ Interval.creates); |
| System.out.println("hits="+ Interval.hits); |
| System.out.println("misses="+ Interval.misses); |
| System.out.println("outOfRange="+ Interval.outOfRange); |
| } |
| */ |
| } |
| } |
| |
| public void sortGrammarFiles() throws IOException { |
| //System.out.println("Grammar names "+getGrammarFileNames()); |
| Graph g = new Graph(); |
| List<String> missingFiles = new ArrayList<String>(); |
| for (String gfile : grammarFileNames) { |
| try { |
| GrammarSpelunker grammar = new GrammarSpelunker(inputDirectory, gfile); |
| grammar.parse(); |
| String vocabName = grammar.getTokenVocab(); |
| String grammarName = grammar.getGrammarName(); |
| // Make all grammars depend on any tokenVocab options |
| if ( vocabName!=null ) g.addEdge(gfile, vocabName+CodeGenerator.VOCAB_FILE_EXTENSION); |
| // Make all generated tokens files depend on their grammars |
| g.addEdge(grammarName+CodeGenerator.VOCAB_FILE_EXTENSION, gfile); |
| } |
| catch (FileNotFoundException fnfe) { |
| ErrorManager.error(ErrorManager.MSG_CANNOT_OPEN_FILE, gfile); |
| missingFiles.add(gfile); |
| } |
| } |
| List<Object> sorted = g.sort(); |
| //System.out.println("sorted="+sorted); |
| grammarFileNames.clear(); // wipe so we can give new ordered list |
| for (int i = 0; i < sorted.size(); i++) { |
| String f = (String)sorted.get(i); |
| if ( missingFiles.contains(f) ) continue; |
| if ( !(f.endsWith(".g") || f.endsWith(".g3")) ) continue; |
| grammarFileNames.add(f); |
| } |
| //System.out.println("new grammars="+grammarFileNames); |
| } |
| |
| /** Get a grammar mentioned on the command-line and any delegates */ |
| public Grammar getRootGrammar(String grammarFileName) |
| throws IOException |
| { |
| //ST.setLintMode(true); |
| // grammars mentioned on command line are either roots or single grammars. |
| // create the necessary composite in case it's got delegates; even |
| // single grammar needs it to get token types. |
| CompositeGrammar composite = new CompositeGrammar(); |
| Grammar grammar = new Grammar(this, grammarFileName, composite); |
| composite.setDelegationRoot(grammar); |
| FileReader fr = null; |
| File f = null; |
| |
| if (haveInputDir) { |
| f = new File(inputDirectory, grammarFileName); |
| } |
| else { |
| f = new File(grammarFileName); |
| } |
| |
| // Store the location of this grammar as if we import files, we can then |
| // search for imports in the same location as the original grammar as well as in |
| // the lib directory. |
| // |
| parentGrammarDirectory = f.getParent(); |
| |
| if (grammarFileName.lastIndexOf(File.separatorChar) == -1) { |
| grammarOutputDirectory = "."; |
| } |
| else { |
| grammarOutputDirectory = grammarFileName.substring(0, grammarFileName.lastIndexOf(File.separatorChar)); |
| } |
| fr = new FileReader(f); |
| BufferedReader br = new BufferedReader(fr); |
| grammar.parseAndBuildAST(br); |
| composite.watchNFAConversion = internalOption_watchNFAConversion; |
| br.close(); |
| fr.close(); |
| return grammar; |
| } |
| |
| /** Create NFA, DFA and generate code for grammar. |
| * Create NFA for any delegates first. Once all NFA are created, |
| * it's ok to create DFA, which must check for left-recursion. That check |
| * is done by walking the full NFA, which therefore must be complete. |
| * After all NFA, comes DFA conversion for root grammar then code gen for |
| * root grammar. DFA and code gen for delegates comes next. |
| */ |
| protected void generateRecognizer(Grammar grammar) { |
| String language = (String) grammar.getOption("language"); |
| if (language != null) { |
| CodeGenerator generator = new CodeGenerator(this, grammar, language); |
| grammar.setCodeGenerator(generator); |
| generator.setDebug(isDebug()); |
| generator.setProfile(isProfile()); |
| generator.setTrace(isTrace()); |
| |
| // generate NFA early in case of crash later (for debugging) |
| if (isGenerate_NFA_dot()) { |
| generateNFAs(grammar); |
| } |
| |
| // GENERATE CODE |
| generator.genRecognizer(); |
| |
| if (isGenerate_DFA_dot()) { |
| generateDFAs(grammar); |
| } |
| |
| List<Grammar> delegates = grammar.getDirectDelegates(); |
| for (int i = 0; delegates != null && i < delegates.size(); i++) { |
| Grammar delegate = (Grammar) delegates.get(i); |
| if (delegate != grammar) { // already processing this one |
| generateRecognizer(delegate); |
| } |
| } |
| } |
| } |
| |
| public void generateDFAs(Grammar g) { |
| for (int d = 1; d <= g.getNumberOfDecisions(); d++) { |
| DFA dfa = g.getLookaheadDFA(d); |
| if (dfa == null) { |
| continue; // not there for some reason, ignore |
| } |
| DOTGenerator dotGenerator = new DOTGenerator(g); |
| String dot = dotGenerator.getDOT(dfa.startState); |
| String dotFileName = g.name + "." + "dec-" + d; |
| if (g.implicitLexer) { |
| dotFileName = g.name + Grammar.grammarTypeToFileNameSuffix[g.type] + "." + "dec-" + d; |
| } |
| try { |
| writeDOTFile(g, dotFileName, dot); |
| } catch (IOException ioe) { |
| ErrorManager.error(ErrorManager.MSG_CANNOT_GEN_DOT_FILE, |
| dotFileName, |
| ioe); |
| } |
| } |
| } |
| |
| protected void generateNFAs(Grammar g) { |
| DOTGenerator dotGenerator = new DOTGenerator(g); |
| Collection rules = g.getAllImportedRules(); |
| rules.addAll(g.getRules()); |
| |
| for (Iterator itr = rules.iterator(); itr.hasNext();) { |
| Rule r = (Rule) itr.next(); |
| try { |
| String dot = dotGenerator.getDOT(r.startState); |
| if (dot != null) { |
| writeDOTFile(g, r, dot); |
| } |
| } catch (IOException ioe) { |
| ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE, ioe); |
| } |
| } |
| } |
| |
| protected void writeDOTFile(Grammar g, Rule r, String dot) throws IOException { |
| writeDOTFile(g, r.grammar.name + "." + r.name, dot); |
| } |
| |
| protected void writeDOTFile(Grammar g, String name, String dot) throws IOException { |
| Writer fw = getOutputFile(g, name + ".dot"); |
| fw.write(dot); |
| fw.close(); |
| } |
| |
| private static void version() { |
| ErrorManager.info("ANTLR Parser Generator Version " + new Tool().VERSION); |
| } |
| |
| private static void help() { |
| ErrorManager.info("ANTLR Parser Generator Version " + new Tool().VERSION); |
| System.err.println("usage: java org.antlr.Tool [args] file.g [file2.g file3.g ...]"); |
| System.err.println(" -o outputDir specify output directory where all output is generated"); |
| System.err.println(" -fo outputDir same as -o but force even files with relative paths to dir"); |
| System.err.println(" -lib dir specify location of token files"); |
| System.err.println(" -depend generate file dependencies"); |
| System.err.println(" -report print out a report about the grammar(s) processed"); |
| System.err.println(" -print print out the grammar without actions"); |
| System.err.println(" -debug generate a parser that emits debugging events"); |
| System.err.println(" -profile generate a parser that computes profiling information"); |
| System.err.println(" -trace generate a recognizer that traces rule entry/exit"); |
| System.err.println(" -nfa generate an NFA for each rule"); |
| System.err.println(" -dfa generate a DFA for each decision point"); |
| System.err.println(" -message-format name specify output style for messages"); |
| System.err.println(" -verbose generate ANTLR version and other information"); |
| System.err.println(" -make only build if generated files older than grammar"); |
| System.err.println(" -version print the version of ANTLR and exit."); |
| System.err.println(" -language L override language grammar option; generate L"); |
| System.err.println(" -X display extended argument list"); |
| } |
| |
| private static void Xhelp() { |
| ErrorManager.info("ANTLR Parser Generator Version " + new Tool().VERSION); |
| System.err.println(" -Xgrtree print the grammar AST"); |
| System.err.println(" -Xdfa print DFA as text "); |
| System.err.println(" -Xnoprune test lookahead against EBNF block exit branches"); |
| System.err.println(" -Xnocollapse collapse incident edges into DFA states"); |
| System.err.println(" -Xdbgconversion dump lots of info during NFA conversion"); |
| System.err.println(" -Xconversiontimeout use to restrict NFA conversion exponentiality"); |
| System.err.println(" -Xmultithreaded run the analysis in 2 threads"); |
| System.err.println(" -Xnomergestopstates do not merge stop states"); |
| System.err.println(" -Xdfaverbose generate DFA states in DOT with NFA configs"); |
| System.err.println(" -Xwatchconversion print a message for each NFA before converting"); |
| System.err.println(" -XdbgST put tags at start/stop of all templates in output"); |
| System.err.println(" -Xnfastates for nondeterminisms, list NFA states for each path"); |
| System.err.println(" -Xm m max number of rule invocations during conversion [" + NFAContext.MAX_SAME_RULE_INVOCATIONS_PER_NFA_CONFIG_STACK + "]"); |
| System.err.println(" -Xmaxdfaedges m max \"comfortable\" number of edges for single DFA state [" + DFA.MAX_STATE_TRANSITIONS_FOR_TABLE + "]"); |
| System.err.println(" -Xmaxinlinedfastates m max DFA states before table used rather than inlining [" + CodeGenerator.MADSI_DEFAULT +"]"); |
| System.err.println(" -Xmaxswitchcaselabels m don't generate switch() statements for dfas bigger than m [" + CodeGenerator.MSCL_DEFAULT +"]"); |
| System.err.println(" -Xminswitchalts m don't generate switch() statements for dfas smaller than m [" + CodeGenerator.MSA_DEFAULT + "]"); |
| System.err.println(" -Xsavelexer don't delete temporary lexers generated from combined grammars"); |
| } |
| |
| /** |
| * Set the threshold of case labels beyond which ANTLR will not instruct the target template |
| * to generate switch() { case xxx: ... |
| * |
| * @param maxSwitchCaseLabels Maximum number of case lables that ANTLR should allow the target code |
| */ |
| public void setMaxSwitchCaseLabels(int maxSwitchCaseLabels) { |
| CodeGenerator.MAX_SWITCH_CASE_LABELS = maxSwitchCaseLabels; |
| } |
| |
| /** |
| * Set the threshold of the number alts, below which ANTLR will not instruct the target |
| * template to use a switch statement. |
| * |
| * @param minSwitchAlts the minimum number of alts required to use a switch staement |
| */ |
| public void setMinSwitchAlts(int minSwitchAlts) { |
| CodeGenerator.MIN_SWITCH_ALTS = minSwitchAlts; |
| } |
| |
| /** |
| * Set the location (base directory) where output files should be produced |
| * by the ANTLR tool. |
| * @param outputDirectory |
| */ |
| public void setOutputDirectory(String outputDirectory) { |
| haveOutputDir = true; |
| this.outputDirectory = outputDirectory; |
| } |
| |
| /** |
| * Used by build tools to force the output files to always be |
| * relative to the base output directory, even though the tool |
| * had to set the output directory to an absolute path as it |
| * cannot rely on the workign directory like command line invocation |
| * can. |
| * |
| * @param forceRelativeOutput true if output files hould always be relative to base output directory |
| */ |
| public void setForceRelativeOutput(boolean forceRelativeOutput) { |
| this.forceRelativeOutput = forceRelativeOutput; |
| } |
| |
| /** |
| * Set the base location of input files. Normally (when the tool is |
| * invoked from the command line), the inputDirectory is not set, but |
| * for build tools such as Maven, we need to be able to locate the input |
| * files relative to the base, as the working directory could be anywhere and |
| * changing workig directories is not a valid concept for JVMs because of threading and |
| * so on. Setting the directory just means that the getFileDirectory() method will |
| * try to open files relative to this input directory. |
| * |
| * @param inputDirectory Input source base directory |
| */ |
| public void setInputDirectory(String inputDirectory) { |
| this.inputDirectory = inputDirectory; |
| haveInputDir = true; |
| } |
| |
| /** This method is used by all code generators to create new output |
| * files. If the outputDir set by -o is not present it will be created. |
| * The final filename is sensitive to the output directory and |
| * the directory where the grammar file was found. If -o is /tmp |
| * and the original grammar file was foo/t.g then output files |
| * go in /tmp/foo. |
| * |
| * The output dir -o spec takes precedence if it's absolute. |
| * E.g., if the grammar file dir is absolute the output dir is given |
| * precendence. "-o /tmp /usr/lib/t.g" results in "/tmp/T.java" as |
| * output (assuming t.g holds T.java). |
| * |
| * If no -o is specified, then just write to the directory where the |
| * grammar file was found. |
| * |
| * If outputDirectory==null then write a String. |
| */ |
| public Writer getOutputFile(Grammar g, String fileName) throws IOException { |
| if (getOutputDirectory() == null) { |
| return new StringWriter(); |
| } |
| // output directory is a function of where the grammar file lives |
| // for subdir/T.g, you get subdir here. Well, depends on -o etc... |
| // But, if this is a .tokens file, then we force the output to |
| // be the base output directory (or current directory if there is not a -o) |
| // |
| File outputDir; |
| if (fileName.endsWith(CodeGenerator.VOCAB_FILE_EXTENSION)) { |
| if (haveOutputDir) { |
| outputDir = new File(getOutputDirectory()); |
| } |
| else { |
| outputDir = new File("."); |
| } |
| } |
| else { |
| outputDir = getOutputDirectory(g.getFileName()); |
| } |
| File outputFile = new File(outputDir, fileName); |
| |
| if (!outputDir.exists()) { |
| outputDir.mkdirs(); |
| } |
| FileWriter fw = new FileWriter(outputFile); |
| return new BufferedWriter(fw); |
| } |
| |
| /** |
| * Return the location where ANTLR will generate output files for a given file. This is a |
| * base directory and output files will be relative to here in some cases |
| * such as when -o option is used and input files are given relative |
| * to the input directory. |
| * |
| * @param fileNameWithPath path to input source |
| * @return |
| */ |
| public File getOutputDirectory(String fileNameWithPath) { |
| |
| File outputDir = new File(getOutputDirectory()); |
| String fileDirectory; |
| |
| // Some files are given to us without a PATH but should should |
| // still be written to the output directory in the relative path of |
| // the output directory. The file directory is either the set of sub directories |
| // or just or the relative path recorded for the parent grammar. This means |
| // that when we write the tokens files, or the .java files for imported grammars |
| // taht we will write them in the correct place. |
| // |
| if (fileNameWithPath.lastIndexOf(File.separatorChar) == -1) { |
| |
| // No path is included in the file name, so make the file |
| // directory the same as the parent grammar (which might sitll be just "" |
| // but when it is not, we will write the file in the correct place. |
| // |
| fileDirectory = grammarOutputDirectory; |
| |
| } |
| else { |
| fileDirectory = fileNameWithPath.substring(0, fileNameWithPath.lastIndexOf(File.separatorChar)); |
| } |
| if (haveOutputDir) { |
| // -o /tmp /var/lib/t.g => /tmp/T.java |
| // -o subdir/output /usr/lib/t.g => subdir/output/T.java |
| // -o . /usr/lib/t.g => ./T.java |
| if ((fileDirectory != null && !forceRelativeOutput) && |
| (new File(fileDirectory).isAbsolute() || |
| fileDirectory.startsWith("~")) || // isAbsolute doesn't count this :( |
| isForceAllFilesToOutputDir()) { |
| // somebody set the dir, it takes precendence; write new file there |
| outputDir = new File(getOutputDirectory()); |
| } |
| else { |
| // -o /tmp subdir/t.g => /tmp/subdir/t.g |
| if (fileDirectory != null) { |
| outputDir = new File(getOutputDirectory(), fileDirectory); |
| } |
| else { |
| outputDir = new File(getOutputDirectory()); |
| } |
| } |
| } |
| else { |
| // they didn't specify a -o dir so just write to location |
| // where grammar is, absolute or relative, this will only happen |
| // with command line invocation as build tools will always |
| // supply an output directory. |
| // |
| outputDir = new File(fileDirectory); |
| } |
| return outputDir; |
| } |
| |
| /** |
| * Name a file from the -lib dir. Imported grammars and .tokens files |
| * |
| * If we do not locate the file in the library directory, then we try |
| * the location of the originating grammar. |
| * |
| * @param fileName input name we are looking for |
| * @return Path to file that we think shuold be the import file |
| * |
| * @throws java.io.IOException |
| */ |
| public String getLibraryFile(String fileName) throws IOException { |
| |
| // First, see if we can find the file in the library directory |
| // |
| File f = new File(getLibraryDirectory() + File.separator + fileName); |
| |
| if (f.exists()) { |
| |
| // Found in the library directory |
| // |
| return f.getAbsolutePath(); |
| } |
| |
| // Need to assume it is in the same location as the input file. Note that |
| // this is only relevant for external build tools and when the input grammar |
| // was specified relative to the source directory (working directory if using |
| // the command line. |
| // |
| return parentGrammarDirectory + File.separator + fileName; |
| } |
| |
| /** Return the directory containing the grammar file for this grammar. |
| * normally this is a relative path from current directory. People will |
| * often do "java org.antlr.Tool grammars/*.g3" So the file will be |
| * "grammars/foo.g3" etc... This method returns "grammars". |
| * |
| * If we have been given a specific input directory as a base, then |
| * we must find the directory relative to this directory, unless the |
| * file name is given to us in absolute terms. |
| */ |
| public String getFileDirectory(String fileName) { |
| |
| File f; |
| if (haveInputDir && !fileName.startsWith(File.separator)) { |
| f = new File(inputDirectory, fileName); |
| } |
| else { |
| f = new File(fileName); |
| } |
| // And ask Java what the base directory of this location is |
| // |
| return f.getParent(); |
| } |
| |
| /** Return a File descriptor for vocab file. Look in library or |
| * in -o output path. antlr -o foo T.g U.g where U needs T.tokens |
| * won't work unless we look in foo too. If we do not find the |
| * file in the lib directory then must assume that the .tokens file |
| * is going to be generated as part of this build and we have defined |
| * .tokens files so that they ALWAYS are generated in the base output |
| * directory, which means the current directory for the command line tool if there |
| * was no output directory specified. |
| */ |
| public File getImportedVocabFile(String vocabName) { |
| |
| File f = new File(getLibraryDirectory(), |
| File.separator + |
| vocabName + |
| CodeGenerator.VOCAB_FILE_EXTENSION); |
| if (f.exists()) { |
| return f; |
| } |
| |
| // We did not find the vocab file in the lib directory, so we need |
| // to look for it in the output directory which is where .tokens |
| // files are generated (in the base, not relative to the input |
| // location.) |
| // |
| if (haveOutputDir) { |
| f = new File(getOutputDirectory(), vocabName + CodeGenerator.VOCAB_FILE_EXTENSION); |
| } |
| else { |
| f = new File(vocabName + CodeGenerator.VOCAB_FILE_EXTENSION); |
| } |
| return f; |
| } |
| |
| /** If the tool needs to panic/exit, how do we do that? |
| */ |
| public void panic() { |
| throw new Error("ANTLR panic"); |
| } |
| |
| /** Return a time stamp string accurate to sec: yyyy-mm-dd hh:mm:ss |
| */ |
| public static String getCurrentTimeStamp() { |
| GregorianCalendar calendar = new java.util.GregorianCalendar(); |
| int y = calendar.get(Calendar.YEAR); |
| int m = calendar.get(Calendar.MONTH) + 1; // zero-based for months |
| int d = calendar.get(Calendar.DAY_OF_MONTH); |
| int h = calendar.get(Calendar.HOUR_OF_DAY); |
| int min = calendar.get(Calendar.MINUTE); |
| int sec = calendar.get(Calendar.SECOND); |
| String sy = String.valueOf(y); |
| String sm = m < 10 ? "0" + m : String.valueOf(m); |
| String sd = d < 10 ? "0" + d : String.valueOf(d); |
| String sh = h < 10 ? "0" + h : String.valueOf(h); |
| String smin = min < 10 ? "0" + min : String.valueOf(min); |
| String ssec = sec < 10 ? "0" + sec : String.valueOf(sec); |
| return new StringBuffer().append(sy).append("-").append(sm).append("-").append(sd).append(" ").append(sh).append(":").append(smin).append(":").append(ssec).toString(); |
| } |
| |
| /** |
| * Provide the List of all grammar file names that the ANTLR tool will |
| * process or has processed. |
| * |
| * @return the grammarFileNames |
| */ |
| public List<String> getGrammarFileNames() { |
| return grammarFileNames; |
| } |
| |
| /** |
| * Indicates whether ANTLR has gnerated or will generate a description of |
| * all the NFAs in <a href="http://www.graphviz.org">Dot format</a> |
| * |
| * @return the generate_NFA_dot |
| */ |
| public boolean isGenerate_NFA_dot() { |
| return generate_NFA_dot; |
| } |
| |
| /** |
| * Indicates whether ANTLR has generated or will generate a description of |
| * all the NFAs in <a href="http://www.graphviz.org">Dot format</a> |
| * |
| * @return the generate_DFA_dot |
| */ |
| public boolean isGenerate_DFA_dot() { |
| return generate_DFA_dot; |
| } |
| |
| /** |
| * Return the Path to the base output directory, where ANTLR |
| * will generate all the output files for the current language target as |
| * well as any ancillary files such as .tokens vocab files. |
| * |
| * @return the output Directory |
| */ |
| public String getOutputDirectory() { |
| return outputDirectory; |
| } |
| |
| /** |
| * Return the Path to the directory in which ANTLR will search for ancillary |
| * files such as .tokens vocab files and imported grammar files. |
| * |
| * @return the lib Directory |
| */ |
| public String getLibraryDirectory() { |
| return libDirectory; |
| } |
| |
| /** |
| * Indicate if ANTLR has generated, or will generate a debug version of the |
| * recognizer. Debug versions of a parser communicate with a debugger such |
| * as that contained in ANTLRWorks and at start up will 'hang' waiting for |
| * a connection on an IP port (49100 by default). |
| * |
| * @return the debug flag |
| */ |
| public boolean isDebug() { |
| return debug; |
| } |
| |
| /** |
| * Indicate whether ANTLR has generated, or will generate a version of the |
| * recognizer that prints trace messages on entry and exit of each rule. |
| * |
| * @return the trace flag |
| */ |
| public boolean isTrace() { |
| return trace; |
| } |
| |
| /** |
| * Indicates whether ANTLR has generated or will generate a version of the |
| * recognizer that gathers statistics about its execution, which it prints when |
| * it terminates. |
| * |
| * @return the profile |
| */ |
| public boolean isProfile() { |
| return profile; |
| } |
| |
| /** |
| * Indicates whether ANTLR has generated or will generate a report of various |
| * elements of the grammar analysis, once it it has finished analyzing a grammar |
| * file. |
| * |
| * @return the report flag |
| */ |
| public boolean isReport() { |
| return report; |
| } |
| |
| /** |
| * Indicates whether ANTLR has printed, or will print, a version of the input grammar |
| * file(s) that is stripped of any action code embedded within. |
| * |
| * @return the printGrammar flag |
| */ |
| public boolean isPrintGrammar() { |
| return printGrammar; |
| } |
| |
| /** |
| * Indicates whether ANTLR has supplied, or will supply, a list of all the things |
| * that the input grammar depends upon and all the things that will be generated |
| * when that grammar is successfully analyzed. |
| * |
| * @return the depend flag |
| */ |
| public boolean isDepend() { |
| return depend; |
| } |
| |
| /** |
| * Indicates whether ANTLR will force all files to the output directory, even |
| * if the input files have relative paths from the input directory. |
| * |
| * @return the forceAllFilesToOutputDir flag |
| */ |
| public boolean isForceAllFilesToOutputDir() { |
| return forceAllFilesToOutputDir; |
| } |
| |
| /** |
| * Indicates whether ANTLR will be verbose when analyzing grammar files, such as |
| * displaying the names of the files it is generating and similar information. |
| * |
| * @return the verbose flag |
| */ |
| public boolean isVerbose() { |
| return verbose; |
| } |
| |
| /** |
| * Provide the current setting of the conversion timeout on DFA creation. |
| * |
| * @return DFA creation timeout value in milliseconds |
| */ |
| public int getConversionTimeout() { |
| return DFA.MAX_TIME_PER_DFA_CREATION; |
| } |
| |
| /** |
| * Returns the current setting of the message format descriptor |
| * @return Current message format |
| */ |
| public String getMessageFormat() { |
| return ErrorManager.getMessageFormat().toString(); |
| } |
| |
| /** |
| * Returns the number of errors that the analysis/processing threw up. |
| * @return Error count |
| */ |
| public int getNumErrors() { |
| return ErrorManager.getNumErrors(); |
| } |
| |
| /** |
| * Indicate whether the tool will analyze the dependencies of the provided grammar |
| * file list and ensure that grammars with dependencies are built |
| * after any of the other gramamrs in the list that they are dependent on. Setting |
| * this option also has the side effect that any grammars that are includes for other |
| * grammars in the list are excluded from individual analysis, which allows the caller |
| * to invoke the tool via org.antlr.tool -make *.g and not worry about the inclusion |
| * of grammars that are just includes for other grammars or what order the grammars |
| * appear on the command line. |
| * |
| * This option was coded to make life easier for tool integration (such as Maven) but |
| * may also be useful at the command line. |
| * |
| * @return true if the tool is currently configured to analyze and sort grammar files. |
| */ |
| public boolean getMake() { |
| return make; |
| } |
| |
| /** |
| * Set the message format to one of ANTLR, gnu, vs2005 |
| * |
| * @param format |
| */ |
| public void setMessageFormat(String format) { |
| ErrorManager.setFormat(format); |
| } |
| |
| /** Provide the List of all grammar file names that the ANTLR tool should process. |
| * |
| * @param grammarFileNames The list of grammar files to process |
| */ |
| public void setGrammarFileNames(List<String> grammarFileNames) { |
| this.grammarFileNames = grammarFileNames; |
| } |
| |
| public void addGrammarFile(String grammarFileName) { |
| if (!grammarFileNames.contains(grammarFileName)) { |
| grammarFileNames.add(grammarFileName); |
| } |
| } |
| |
| /** |
| * Indicate whether ANTLR should generate a description of |
| * all the NFAs in <a href="http://www.graphviz.org">Dot format</a> |
| * |
| * @param generate_NFA_dot True to generate dot descriptions |
| */ |
| public void setGenerate_NFA_dot(boolean generate_NFA_dot) { |
| this.generate_NFA_dot = generate_NFA_dot; |
| } |
| |
| /** |
| * Indicates whether ANTLR should generate a description of |
| * all the NFAs in <a href="http://www.graphviz.org">Dot format</a> |
| * |
| * @param generate_DFA_dot True to generate dot descriptions |
| */ |
| public void setGenerate_DFA_dot(boolean generate_DFA_dot) { |
| this.generate_DFA_dot = generate_DFA_dot; |
| } |
| |
| /** |
| * Set the Path to the directory in which ANTLR will search for ancillary |
| * files such as .tokens vocab files and imported grammar files. |
| * |
| * @param libDirectory the libDirectory to set |
| */ |
| public void setLibDirectory(String libDirectory) { |
| this.libDirectory = libDirectory; |
| } |
| |
| /** |
| * Indicate whether ANTLR should generate a debug version of the |
| * recognizer. Debug versions of a parser communicate with a debugger such |
| * as that contained in ANTLRWorks and at start up will 'hang' waiting for |
| * a connection on an IP port (49100 by default). |
| * |
| * @param debug true to generate a debug mode parser |
| */ |
| public void setDebug(boolean debug) { |
| this.debug = debug; |
| } |
| |
| /** |
| * Indicate whether ANTLR should generate a version of the |
| * recognizer that prints trace messages on entry and exit of each rule |
| * |
| * @param trace true to generate a tracing parser |
| */ |
| public void setTrace(boolean trace) { |
| this.trace = trace; |
| } |
| |
| /** |
| * Indicate whether ANTLR should generate a version of the |
| * recognizer that gathers statistics about its execution, which it prints when |
| * it terminates. |
| * |
| * @param profile true to generate a profiling parser |
| */ |
| public void setProfile(boolean profile) { |
| this.profile = profile; |
| } |
| |
| /** |
| * Indicate whether ANTLR should generate a report of various |
| * elements of the grammar analysis, once it it has finished analyzing a grammar |
| * file. |
| * |
| * @param report true to generate the analysis report |
| */ |
| public void setReport(boolean report) { |
| this.report = report; |
| } |
| |
| /** |
| * Indicate whether ANTLR should print a version of the input grammar |
| * file(s) that is stripped of any action code embedded within. |
| * |
| * @param printGrammar true to generate a stripped file |
| */ |
| public void setPrintGrammar(boolean printGrammar) { |
| this.printGrammar = printGrammar; |
| } |
| |
| /** |
| * Indicate whether ANTLR should supply a list of all the things |
| * that the input grammar depends upon and all the things that will be generated |
| * when that gramamr is successfully analyzed. |
| * |
| * @param depend true to get depends set rather than process the grammar |
| */ |
| public void setDepend(boolean depend) { |
| this.depend = depend; |
| } |
| |
| /** |
| * Indicates whether ANTLR will force all files to the output directory, even |
| * if the input files have relative paths from the input directory. |
| * |
| * @param forceAllFilesToOutputDir true to force files to output directory |
| */ |
| public void setForceAllFilesToOutputDir(boolean forceAllFilesToOutputDir) { |
| this.forceAllFilesToOutputDir = forceAllFilesToOutputDir; |
| } |
| |
| /** |
| * Indicate whether ANTLR should be verbose when analyzing grammar files, such as |
| * displaying the names of the files it is generating and similar information. |
| * |
| * @param verbose true to be verbose |
| */ |
| public void setVerbose(boolean verbose) { |
| this.verbose = verbose; |
| } |
| |
| /** |
| * Indicate whether the tool should analyze the dependencies of the provided grammar |
| * file list and ensure that the grammars with dependencies are built |
| * after any of the other gramamrs in the list that they are dependent on. Setting |
| * this option also has the side effect that any grammars that are includes for other |
| * grammars in the list are excluded from individual analysis, which allows the caller |
| * to invoke the tool via org.antlr.tool -make *.g and not worry about the inclusion |
| * of grammars that are just includes for other grammars or what order the grammars |
| * appear on the command line. |
| * |
| * This option was coded to make life easier for tool integration (such as Maven) but |
| * may also be useful at the command line. |
| * |
| * @param make |
| */ |
| public void setMake(boolean make) { |
| this.make = make; |
| } |
| |
| } |