internal void Generate(List <AutomatonState> states)
        {
            StreamWriter tWrtr   = null;
            StreamWriter cstWrtr = null;
            StreamWriter sWrtr   = null;
            StreamWriter cWrtr   = null;
            TextWriter   save    = Console.Out;
            //
            // Did we specify output filename in command line or
            // the file (if both, the command line takes precedence)?
            //
            string outFile = GPCG.OutFileName;

            if (outFile == null)
            {
                outFile = grammar.OutFileName;
            }

            if (outFile != null)
            {
                try
                {
                    FileStream fStrm = new FileStream(outFile, FileMode.Create);
                    sWrtr = new StreamWriter(fStrm);
                    Console.WriteLine("GPPG: sending output to {0}", outFile);
                    Console.SetOut(sWrtr);
                }
                catch (IOException x)
                {
                    Console.Error.WriteLine("GPPG: Error. File redirect failed");
                    Console.Error.WriteLine(x.Message);
                    Console.Error.WriteLine("GPPG: Terminating ...");
                    Environment.Exit(1);
                }
            }

            if (grammar.TokFileName != null) // generate token list file
            {
                try {
                    FileStream fStrm = new FileStream(grammar.TokFileName, FileMode.Create);
                    tWrtr = new StreamWriter(fStrm);
                    tWrtr.WriteLine("// Symbolic tokens for grammar file \"{0}\"", grammar.InputFileIdent);
                }
                catch (IOException x) {
                    Console.Error.WriteLine("GPPG: Error. Failed to create token namelist file");
                    Console.Error.WriteLine(x.Message);
                    tWrtr = null;
                }
            }

            if (grammar.CsTokFileName != null) // generate C# token declaration file
            {
                try {
                    FileStream fStrm = new FileStream(grammar.CsTokFileName, FileMode.Create);
                    cstWrtr = new StreamWriter(fStrm);
                    cstWrtr.WriteLine("// Token declarations  for grammar file \"{0}\"", grammar.InputFileIdent);
                }
                catch (IOException x) {
                    Console.Error.WriteLine("GPPG: Error. Failed to create C# token declaration file");
                    Console.Error.WriteLine(x.Message);
                    cstWrtr = null;
                }
            }

            if (GPCG.ShareTokens && grammar.DatFileName != null) // serialize Terminals dictionary.
            {
                FileStream fStrm = null;
                try {
                    // Insert marker to carry Terminal.max into the serialized structure.
                    Terminal.InsertMaxDummyTerminalInDictionary(grammar.terminals);

                    fStrm = new FileStream(grammar.DatFileName, FileMode.Create);
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(fStrm, grammar.terminals);
                }
                catch (IOException x) {
                    Console.Error.WriteLine("GPPG: Error. Failed to create token serialization file");
                    Console.Error.WriteLine(x.Message);
                }
                finally {
                    if (fStrm != null)
                    {
                        fStrm.Close();
                    }
                    Terminal.RemoveMaxDummyTerminalFromDictionary(grammar.terminals);
                }
            }

            if (grammar.DiagFileName != null) // generate conflict list file
            {
                try
                {
                    FileStream cStrm = new FileStream(grammar.DiagFileName, FileMode.Create);
                    cWrtr = new StreamWriter(cStrm);
                    cWrtr.WriteLine("// Parser Conflict Information for grammar file \"{0}\"", grammar.InputFileIdent);
                    cWrtr.WriteLine();
                }
                catch (IOException x)
                {
                    Console.Error.WriteLine("GPPG: Error. Failed to create conflict information file");
                    Console.Error.WriteLine(x.Message);
                    cWrtr = null;
                }
            }

            GenerateCopyright();

            GenerateUsingHeader();

            if (grammar.Namespace != null)
            {
                Console.WriteLine("namespace {0}", grammar.Namespace);
                Console.WriteLine('{');
            }
            //
            // Emit token enumeration
            //
            if (!GPCG.ImportedTokens)
            {
                if (GPCG.CsTokenFile)
                {
                    GenerateCsTokenFile(cstWrtr, tWrtr);
                }
                else
                {
                    GenerateInlineTokens(grammar.terminals, tWrtr);
                }
            }
            //
            // Report any conflicts
            //
            grammar.ReportConflicts(cWrtr);
            //
            // Now emit the parser class.
            //
            GenerateClassHeader(grammar.ParserName);
            if (grammar.prologCode.Count > 0)
            {
                Console.WriteLine("  // Verbatim content from {0}", grammar.InputFileIdent);
                foreach (LexSpan span in grammar.prologCode)
                {
                    InsertCodeSpan(span);
                }
                Console.WriteLine("  // End verbatim content from {0}", grammar.InputFileIdent);
                Console.WriteLine();
            }
            GenerateInitializeMethod(states, grammar.productions, grammar.nonTerminals);
            GenerateShiftReduceMachineActions(grammar.productions);
            GenerateToStringMethod();
            InsertCodeSpan(grammar.epilogCode);
            GenerateClassFooter();

            if (grammar.Namespace != null)
            {
                Console.WriteLine('}');
            }

            if (tWrtr != null)
            {
                tWrtr.WriteLine("// End symbolic tokens for parser");
                tWrtr.Close(); // Close the optional token name stream
            }

            if (cstWrtr != null)
            {
                cstWrtr.Close(); // Close the optional token declaration stream
            }

            if (cWrtr != null)
            {
                cWrtr.WriteLine("// End conflict information for parser");
                cWrtr.Close(); // Close the optional token name stream
            }

            if (sWrtr != null)
            {
                Console.SetOut(save);
                sWrtr.Close();
            }
        }
Esempio n. 2
0
        internal void Generate(List <AutomatonState> states, Grammar grammar)
        {
            StreamWriter tWrtr = null;
            StreamWriter sWrtr = null;
            StreamWriter cWrtr = null;
            TextWriter   save  = Console.Out;

            this.grammar = grammar;
            if (grammar.OutFileName != null)
            {
                try
                {
                    FileStream fStrm = new FileStream(grammar.OutFileName, FileMode.Create);
                    sWrtr = new StreamWriter(fStrm);
                    Console.WriteLine("GPPG: sending output to {0}", grammar.OutFileName);
                    Console.SetOut(sWrtr);
                }
                catch (IOException x)
                {
                    Console.Error.WriteLine("GPPG: Error. File redirect failed");
                    Console.Error.WriteLine(x.Message);
                    Console.Error.WriteLine("GPPG: Terminating ...");
                    Environment.Exit(1);
                }
            }

            if (grammar.TokFileName != null) // generate token list file
            {
                try
                {
                    FileStream fStrm = new FileStream(grammar.TokFileName, FileMode.Create);
                    tWrtr = new StreamWriter(fStrm);
                    tWrtr.WriteLine("// Symbolic tokens for parser for grammar file \"{0}\"", grammar.InputFileName);
                }
                catch (IOException x)
                {
                    Console.Error.WriteLine("GPPG: Error. Failed to create token namelist file");
                    Console.Error.WriteLine(x.Message);
                    tWrtr = null;
                }
            }

            if (grammar.DiagFileName != null) // generate conflict list file
            {
                try
                {
                    FileStream cStrm = new FileStream(grammar.DiagFileName, FileMode.Create);
                    cWrtr = new StreamWriter(cStrm);
                    cWrtr.WriteLine("// Parser Conflict Information for grammar file \"{0}\"", grammar.InputFileName);
                    cWrtr.WriteLine();
                }
                catch (IOException x)
                {
                    Console.Error.WriteLine("GPPG: Error. Failed to create conflict information file");
                    Console.Error.WriteLine(x.Message);
                    cWrtr = null;
                }
            }

            GenerateCopyright();

            GenerateUsingHeader();

            if (grammar.Namespace != null)
            {
                Console.WriteLine("namespace {0}", grammar.Namespace);
                Console.WriteLine('{');
            }

            GenerateTokens(grammar.terminals, tWrtr);
            grammar.ReportConflicts(cWrtr);

            GenerateClassHeader(grammar.ParserName);
            foreach (LexSpan span in grammar.prologCode)
            {
                InsertCodeSpan(span);
            }
            GenerateInitializeMethod(states, grammar.productions, grammar.nonTerminals);
            GenerateActionMethod(grammar.productions);
            GenerateToStringMethod();
            InsertCodeSpan(grammar.epilogCode);
            GenerateClassFooter();

            if (grammar.Namespace != null)
            {
                Console.WriteLine('}');
            }

            if (tWrtr != null)
            {
                tWrtr.WriteLine("// End symbolic tokens for parser");
                tWrtr.Close(); // Close the optional token name stream
            }

            if (cWrtr != null)
            {
                cWrtr.WriteLine("// End conflict information for parser");
                cWrtr.Close(); // Close the optional token name stream
            }

            if (sWrtr != null)
            {
                Console.SetOut(save);
                sWrtr.Close();
            }
        }