예제 #1
0
파일: Main.cs 프로젝트: deAtog/gppg
        private static int Main( string[] args )
        {
            Stream inputFile = null;

            Grammar grammar = null;
            ErrorHandler handler = new ErrorHandler();
            string inputFileInfo = null;  // Filename plus revision time.
            Lexers.Scanner scanner = null;
            Parser.Parser parser = null;
            Assembly assm = Assembly.GetExecutingAssembly();
            object info = Attribute.GetCustomAttribute( assm, typeof( AssemblyFileVersionAttribute ) );
            versionInfo = ((AssemblyFileVersionAttribute)info).Version;

            try {
                string filename = ProcessOptions( args );

                if (filename == null)
                    return MC_OK;

                try {
                    inputFile = new FileStream( filename, FileMode.Open, FileAccess.Read, FileShare.Read );
                    inputFileInfo = filename + " - " + File.GetLastWriteTime( filename ).ToString();
                }
                catch (IOException x) {
                    string message;
                    inputFile = null;
                    if (x is FileNotFoundException)
                        message = String.Format( CultureInfo.InvariantCulture,
                            "Source file <{0}> not found{1}",
                            filename, Environment.NewLine );
                    else
                        message = String.Format( CultureInfo.InvariantCulture,
                            "Source file <{0}> could not be opened{1}",
                            filename, Environment.NewLine );
                    handler.AddError( 4, message, null ); // aast.AtStart;
                    return MC_FILEERROR;
                }

                scanner = new Lexers.Scanner( inputFile );
                scanner.SetHandler( handler );

                parser = new Parser.Parser( filename, inputFileInfo, scanner, handler );
                //
                // If the parse is successful, then process the grammar.
                // Otherwise just report the errors that have been listed.
                //
                if (parser.Parse()) {
                    grammar = parser.Grammar;

                    if (Terminal.Max > 255)
                        handler.ListError( null, 103, CharacterUtilities.Map( Terminal.Max ), '\'' );

                    LALRGenerator generator = new LALRGenerator( grammar );
                    List<AutomatonState> states = generator.BuildStates();
                    generator.ComputeLookAhead();
                    generator.BuildParseTable();
                    if (!grammar.CheckGrammar( handler ))
                        throw new ArgumentException( "Non-terminating grammar" );
                    //
                    // If the grammar has non-terminating non-terms we cannot
                    // create a diagnostic report as the grammar is incomplete.
                    //
                    if (!handler.Errors) {
                        CodeGenerator code = new CodeGenerator();
                        code.Generate( states, grammar );
                    }

                    bool DoDiagnose = Diagnose && !grammar.HasNonTerminatingNonTerms;
                    if (Report || DoDiagnose) {
                        string htmlName = System.IO.Path.ChangeExtension( filename, ".report.html" );
                        try {
                            System.IO.FileStream htmlFile = new System.IO.FileStream( htmlName, System.IO.FileMode.Create );
                            System.IO.StreamWriter htmlWriter = new System.IO.StreamWriter( htmlFile );
                            Grammar.HtmlHeader( htmlWriter, filename );

                            if (Report && DoDiagnose)
                                grammar.GenerateCompoundReport( htmlWriter, inputFileInfo, states );
                            else if (Report)
                                grammar.GenerateReport( htmlWriter, inputFileInfo, states );

                            Grammar.HtmlTrailer( htmlWriter );

                            if (htmlFile != null) {
                                htmlWriter.Flush();
                                htmlFile.Close();
                            }
                        }
                        catch (System.IO.IOException) {
                            Console.Error.WriteLine( "Cannot create html output file {0}", htmlName );
                        }
                    }
                }
            }
            catch (System.Exception e) {
                if (e is TooManyErrorsException)
                    return MC_TOOMANYERRORS;
                Console.Error.WriteLine( "Unexpected Error {0}", e.Message );

                if (NoThrowOnError) {
                    // report the error, do not let it go into the void
                    Console.Error.WriteLine( e );
                    return MC_EXCEPTION;
                }
            }
            finally {
                if (handler.Errors || handler.Warnings)
                    handler.DumpAll( (scanner == null ? null : scanner.Buffer), Console.Error );
                if ((Listing || handler.Errors || handler.Warnings) && parser != null) {
                    string listName = parser.ListfileName;
                    StreamWriter listStream = ListingFile( listName );
                    if (listStream != null)
                        handler.MakeListing( scanner.Buffer, listStream, parser.SourceFileInfo, versionInfo );
                }
            }
            return MC_OK;
        }
예제 #2
0
        // Modified code contributed by Emmo Emminghaus.
        internal void GenerateCode( CodeGenerator codeGenerator )
        {
            int i = 0;
            int line = codeSpan.startLine;
            bool doLines = GPCG.Lines;

            int length = commands.Length;
            if (doLines) {
                Console.WriteLine( "#line {0} \"{1}\"", line, GPCG.LinesFilename ?? codeGenerator.grammar.InputFilename );
                for (int j = 0; j < codeSpan.startColumn; j++)
                    Console.Write( " " );
            }

            while (i < length) {
                switch (commands[i]) {
                    case 'Y': {
                            int j = i;
                            do { j++; } while (j < length && char.IsLetter( commands, j ));
                            string substr = commands.Substring( i, j - i );
                            if (substr.Equals( "YYACCEPT" )) {
                                i = j;
                                Console.Write( "YYAccept()" );
                            }
                            else if (substr.Equals( "YYABORT" )) {
                                i = j;
                                Console.Write( "YYAbort()" );
                            }
                            else if (substr.Equals( "YYERROR" )) {
                                i = j;
                                Console.Write( "YYError()" );
                            }
                            else
                                Output( i++ );
                            break;
                        }
                    case '/':
                        Output( i++ );
                        if (i < length && commands[i] == '/') // C++ style comments
                        {
                            while (i < length && commands[i] != '\n')
                                Output( i++ );
                            if (i < length)
                                Output( i++ );
                        }
                        else if (i < length && commands[i] == '*') // C style comments
                        {
                            Output( i++ );
                            do {
                                while (i < length && commands[i] != '*')
                                    Output( i++ );
                                if (i < length)
                                    Output( i++ );
                            } while (i < length && commands[i] != '/');
                            if (i < length)
                                Output( i++ );
                        }
                        break;
                    case '"':       // start of string literal
                        Output( i++ );
                        while (i < length && commands[i] != '"') {
                            if (commands[i] == '\\')
                                Output( i++ );
                            if (i < length)
                                Output( i++ );
                        }
                        if (i < length)
                            Output( i++ );
                        break;

                    case '@':
                        // Possible start of verbatim string literal
                        // but also possible location marker access
                        if (i + 1 < length) {
                            char la = commands[i + 1]; // lookahead character
                            if (la == '$') {
                                i += 2; // read past '@', '$'
                                Console.Write( "CurrentLocationSpan" );
                            }
                            else if (Char.IsDigit( la )) {
                                i++;
                                int num = (int)commands[i++] - (int)'0';
                                while (i < length && char.IsDigit( commands[i] ))
                                    num = num * 10 + (int)commands[i++] - (int)'0';

                                //if (num > this.production.rhs.Count)
                                //    ErrReport(lineTag, String.Format("Index @{0} is out of bounds", num));
                                Console.Write( "LocationStack[LocationStack.Depth-{0}]", pos - num + 1 );
                            }
                            else {
                                Output( i++ );
                                if (la == '"') {
                                    Output( i++ );
                                    while (i < length && commands[i] != '"')
                                        Output( i++ );
                                    if (i < length)
                                        Output( i++ );
                                    break;
                                }
                            }
                        }
                        //else
                        //    ErrReport(lineTag, "Invalid use of '@'");
                        break;

                    case '\'':      // start of char literal
                        Output( i++ );
                        while (i < length && commands[i] != '\'') {
                            if (commands[i] == '\\')
                                Output( i++ );
                            if (i < length)
                                Output( i++ );
                        }
                        if (i < length)
                            Output( i++ );
                        break;

                    case '$':       // $$ or $n placeholder
                        i++;
                        if (i < length) {
                            string kind = null;
                            if (commands[i] == '<') // $<kind>n
                            {
                                i++;
                                StringBuilder builder = new StringBuilder();
                                while (i < length && commands[i] != '>') {
                                    builder.Append( commands[i] );
                                    i++;
                                }
                                if (i < length) {
                                    i++;
                                    kind = builder.ToString();
                                }
                            }

                            if (commands[i] == '$') {
                                i++;
                                if (kind == null)
                                    kind = production.lhs.kind;

                                Console.Write( "CurrentSemanticValue" );

                                if (kind != null)
                                    Console.Write( ".{0}", kind );
                            }
                            else if (char.IsDigit( commands[i] )) {
                                int num = (int)commands[i++] - (int)'0';
                                while (i < length && char.IsDigit( commands[i] ))
                                    num = num * 10 + (int)commands[i++] - (int)'0';

                                //if (num > this.production.rhs.Count)
                                //    ErrReport(lineTag, String.Format("Index ${0} is out of bounds", num));

                                if (kind == null)
                                    kind = production.rhs[num - 1].kind;

                                Console.Write( "ValueStack[ValueStack.Depth-{0}]", pos - num + 1 );

                                if (kind != null)
                                    Console.Write( ".{0}", kind );
                            }
                        }
                        //else
                        //    ErrReport(lineTag, "Unexpected '$'");
                        break;

                    case '\n':
                        Output( i );
                        i++;
                        line++;
                        break;

                    default:
                        Output( i++ );
                        break;
                }
            }
            Console.WriteLine();
            if (doLines)
                Console.WriteLine( "#line default" );
        }