public ProcessSystem Parse(string inputFile)
 {
     Parser p = new Parser(new Scanner(inputFile));
     StringWriter errorWriter = new StringWriter();
     p.errors.errorStream = errorWriter;
     p.Parse();
     if (p.errors.count > 0) {
         throw new ParseException(errorWriter.ToString());
     }
     return p.System;
 }
        static int Main(string[] args)
        {
            if (args.Length == 0) {
                Console.Error.WriteLine(@"
            CCS Compiler
            Copyright (C) 2009 Einar Egilsson

            Usage: CCS [options] <filename>
            ");
                return 1;
            }
            List<string> listArgs = new List<string>(args);
            CompileOptions.AddOptionWithArgument("p", "print", ""); //Allow printouts
            CompileOptions options = CompileOptions.Parse(listArgs);

            if (options.Help) {
                Console.Error.WriteLine(@"
            CCS Compiler
            Copyright (C) 2009 Einar Egilsson

            Usage: CCS [options] <filename>

            Available options:

            /reference:<filenames>   The assemblies that this program requires. It is
            /r:<filenames>           not neccessary to specify the PLR assembly.
                             Other assemblies should be specified in a comma
                             seperated list, e.g. /reference:Foo.dll,Bar.dll.

            /optimize                If specified then the generated assembly will be
            /op                      optimized, dead code eliminated and expressions
                             pre-evaluated where possible. Do not combine this
                             with the /debug switch.

            /embedPLR                Embeds the PLR into the generated file, so it can
            /e                       be distributed as a stand-alone file.

            /debug                   Emit debugging symbols in the generated file,
            /d                       this allows it to be debugged in Visual Studio, or
                             in the free graphical debugger that comes with the
                             .NET Framework SDK.

            /out:<filename>          Specify the name of the compiled executable. If
            /o:<filename>            this is not specified then the name of the input
                             file is used, with .ccs replaced by .exe.

            /print:<format>          Prints a version of the program source in the
            /p:<format>              specified format. Allowed formats are ccs, html
                             and latex. The generated file will have the same
                             name as the input file, except with the format
                             as extension.

            ");

                return 1;
            }

            DieIf(options.Arguments.Count == 0, "ERROR: Missing input file name");
            DieIf(options.Arguments.Count > 1, "ERROR: Only one input file is expected");
            string filename = options.Arguments[0];
            DieIf(!File.Exists(filename), "ERROR: File '{0}' does not exist!", filename);
            if (string.IsNullOrEmpty(options.OutputFile)) {
                options.OutputFile = filename;
                if (options.OutputFile.ToLower().EndsWith(".ccs")) {
                    options.OutputFile = options.OutputFile.Substring(0, options.OutputFile.Length - 4);
                }
            }
            if (!options.OutputFile.ToLower().EndsWith(".exe")) {
                options.OutputFile += ".exe";
            }
            try {

                Parser parser = new Parser(new Scanner(new FileStream(filename, FileMode.Open)));
                parser.Parse();
                if (parser.errors.count > 0) {
                    Environment.Exit(1);
                }
                ProcessSystem system = parser.System;
                system.MeetTheParents();
                List<Warning> warnings = system.Analyze(new ReachingDefinitions());

                if (warnings.Count > 0) {
                    foreach (Warning warn in warnings) {
                        Console.Error.WriteLine("ERROR({0},{1}): {2}", warn.LexicalInfo.StartLine, warn.LexicalInfo.StartColumn, warn.Message);
                    }
                    return 1; //This is an error so we die before attempting to compile
                }

                //These are just warnings, so just warn...
                warnings = system.Analyze(
                    new LiveVariables(),
                    new NilProcessWarning(),
                    new UnmatchedChannels(),
                    new UnusedProcesses(options.Optimize)
                );

                foreach (Warning warn in warnings) {
                    Console.Error.WriteLine("WARNING({0},{1}): {2}", warn.LexicalInfo.StartLine, warn.LexicalInfo.StartColumn, warn.Message);
                }

                //This optimizes the tree before compilation, only do if we should optimize
                if (options.Optimize) {
                    system.Analyze(new FoldConstantExpressions());
                }

                CheckPrintout(options, system);
                system.Compile(options);
            } catch (Exception ex) {
                //Console.WriteLine(ex.StackTrace);
                DieIf(true, "ERROR: " + ex.Message);
            }
            return 0;
        }
 public PLR.AST.ProcessSystem Parse(System.IO.Stream inputStream)
 {
     Parser p = new Parser(new Scanner(inputStream));
     p.Parse();
     return p.System;
 }