public virtual void Process() { bool exceptionWhenWritingLexerFile = false; string lexerGrammarFileName = null; // necessary at this scope to have access in the catch below Stopwatch timer = Stopwatch.StartNew(); // 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 ( Verbose && showBanner ) { ErrorManager.Info( "ANTLR Parser Generator Version " + AssemblyInformationalVersion ); showBanner = false; } try { SortGrammarFiles(); // update grammarFileNames } catch ( Exception e ) { ErrorManager.Error( ErrorManager.MSG_INTERNAL_ERROR, e ); } foreach ( string grammarFileName in 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 ( Verbose && !Depend ) { Console.Out.WriteLine( grammarFileName ); } try { if ( Depend ) { BuildDependencyGenerator dep = new BuildDependencyGenerator( this, grammarFileName ); #if false IList<string> outputFiles = dep.getGeneratedFileList(); IList<string> dependents = dep.getDependenciesFileList(); Console.Out.WriteLine( "output: " + outputFiles ); Console.Out.WriteLine( "dependents: " + dependents ); #endif Console.Out.WriteLine( 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 ( PrintGrammar ) { rootGrammar.PrintGrammar( Console.Out ); } if (Report) { GrammarReport2 greport = new GrammarReport2(rootGrammar); Console.WriteLine(greport.ToString()); } if ( Profile ) { GrammarReport report = new GrammarReport(rootGrammar); Stats.WriteReport( GrammarReport.GRAMMAR_STATS_FILENAME, report.ToNotifyString() ); } // now handle the lexer if one was created for a merged spec string lexerGrammarStr = rootGrammar.GetLexerGrammar(); //[email protected]("lexer grammar:\n"+lexerGrammarStr); if ( rootGrammar.type == GrammarType.Combined && lexerGrammarStr != null ) { lexerGrammarFileName = rootGrammar.ImplicitlyGeneratedLexerFileName; try { TextWriter w = GetOutputFile( rootGrammar, lexerGrammarFileName ); w.Write( lexerGrammarStr ); w.Close(); } catch (IOException) { // emit different error message when creating the implicit lexer fails // due to write permission error exceptionWhenWritingLexerFile = true; throw; } try { StringReader sr = new StringReader( lexerGrammarStr ); Grammar lexerGrammar = new Grammar(this); lexerGrammar.composite.WatchNFAConversion = internalOption_watchNFAConversion; lexerGrammar.implicitLexer = true; if ( TestMode ) lexerGrammar.DefaultRuleModifier = "public"; FileInfo lexerGrammarFullFile = new FileInfo( System.IO.Path.Combine( GetFileDirectory( lexerGrammarFileName ), lexerGrammarFileName ) ); lexerGrammar.FileName = 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 ) { System.IO.DirectoryInfo outputDir = GetOutputDirectory( lexerGrammarFileName ); FileInfo outputFile = new FileInfo( System.IO.Path.Combine( outputDir.FullName, 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, e ); } } catch ( Exception e ) { ErrorManager.Error( ErrorManager.MSG_INTERNAL_ERROR, grammarFileName, e ); } #if false finally { Console.Out.WriteLine( "creates=" + Interval.creates ); Console.Out.WriteLine( "hits=" + Interval.hits ); Console.Out.WriteLine( "misses=" + Interval.misses ); Console.Out.WriteLine( "outOfRange=" + Interval.outOfRange ); } #endif } if (_showTimer) { Console.WriteLine("Total parse time: {0}ms", timer.ElapsedMilliseconds); } }
/** * 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 * @param outputFiles * @return */ public virtual bool BuildRequired( string grammarFileName ) { BuildDependencyGenerator bd = new BuildDependencyGenerator( this, grammarFileName ); IList<string> outputFiles = bd.GetGeneratedFileList(); IList<string> inputFiles = bd.GetDependenciesFileList(); DateTime grammarLastModified = File.GetLastWriteTime( grammarFileName ); foreach ( string outputFile in outputFiles ) { if ( !File.Exists( outputFile ) || grammarLastModified > File.GetLastWriteTime( outputFile ) ) { // One of the output files does not exist or is out of date, so we must build it if (Verbose) { if (!File.Exists(outputFile)) Console.Out.WriteLine("Output file " + outputFile + " does not exist: must build " + grammarFileName); else Console.Out.WriteLine("Output file " + outputFile + " is not up-to-date: must build " + grammarFileName); } 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 ) { foreach ( string inputFile in inputFiles ) { if ( File.GetLastWriteTime( inputFile ) > File.GetLastWriteTime( outputFile ) ) { // One of the imported grammar files has been updated so we must build if (Verbose) Console.Out.WriteLine("Input file " + inputFile + " is newer than output: must rebuild " + grammarFileName); return true; } } } } if ( Verbose ) { Console.Out.WriteLine( "Grammar " + grammarFileName + " is up to date - build skipped" ); } return false; }