Example #1
0
        public void CheckGrammarCorrectness()
        {
            int STOP_AFTER_AS_MANY_ERRORS = 1000;
            string regex = "*.PGM";
            string samples = @"Samples";
            string root = PlatformUtils.GetPathForProjectFile(samples);
            string[] files = Directory.GetFiles(root, regex, System.IO.SearchOption.AllDirectories);
            string[] include = { };
            string[] exclude = { };
            bool codegen = true;
            var format = TypeCobol.Compiler.DocumentFormat.RDZReferenceFormat;

            System.IO.File.WriteAllText("CheckGrammarResults.txt", "");
            int tested = 0, nbFilesInError = 0, ignores = 0;
            TimeSpan sum = new TimeSpan(0);
            int parseErrors = 0;
            int codegenErrors = 0;
            foreach (var file in files) {

                string filename = Path.GetFileName(file);
                System.IO.File.AppendAllText("CheckGrammarResults.txt", (filename + ':'));
                bool ignore = include.Length > 0 && !include.Contains(filename);
                if (!ignore) ignore = exclude.Contains(filename);
                if (ignore) {
                    ignores++;
                    System.IO.File.AppendAllText("CheckGrammarResults.txt", " ignored.\n");
                    continue;
                }
                string path = Path.Combine(root, filename);
                Stopwatch watch = new Stopwatch();
                watch.Start();
                var document = Parser.Parse(path, format);
                watch.Stop();
                //TestJSONSerializer.DumpAsJSON(unit.CodeElementsDocumentSnapshot.CodeElements, filename);
                TimeSpan elapsed = watch.Elapsed;
                sum += elapsed;
                string formatted = String.Format("{0:00}m{1:00}s{2:000}ms", elapsed.Minutes, elapsed.Seconds, elapsed.Milliseconds);
                System.IO.File.AppendAllText("CheckGrammarResults.txt", (" parsed in " + formatted + "\n"));

                tested++;
                bool okay = true;
                if(hasErrors(document.Results.CodeElementsDocumentSnapshot)) {
                    okay = false;
                    parseErrors += checkErrors(filename, document.Results.CodeElementsDocumentSnapshot.ParserDiagnostics);
                }
                if(hasErrors(document.Results.ProgramClassDocumentSnapshot)) {
                    okay = false;
                    parseErrors += checkErrors(filename, document.Results.ProgramClassDocumentSnapshot.Diagnostics);
                }
                if (!okay) {
                    nbFilesInError++;
                    if (nbFilesInError >= STOP_AFTER_AS_MANY_ERRORS) break;
                }

                if (codegen) {
                    var writer = new StringWriter();
                    var generator = new TypeCobol.Codegen.Generator(writer, document.Results.TokensLines, null);
                    var program = document.Results.ProgramClassDocumentSnapshot.Program;
                    var columns = document.Results.ProgramClassDocumentSnapshot.TextSourceInfo.ColumnsLayout;
                    generator.Generate(program.SyntaxTree.Root, program.SymbolTable, columns);
                    writer.Close();

                    var expected = AsLines(File.ReadAllText(path, format.Encoding));
                    var actual = AsLines(writer.ToString());
                    var linesKO = new List<int>();
                    for(int i=0; i<Math.Min(expected.Count, actual.Count); i++) {
                        if (!expected[i].Equals(actual[i])) linesKO.Add(i);
                    }
                    var errors = new System.Text.StringBuilder();
                    string fmt = Lines2FormatString(Math.Max(expected.Count, actual.Count));
                    if (linesKO.Count > 0 || expected.Count != actual.Count) errors.AppendLine("--- Lines mismatch ---");
                    int start = -1;
                    for (int i=0; i<linesKO.Count; i++) {
                        int currentline = linesKO[i];
                        bool follows = i > 0 && linesKO[i-1] == currentline-1;
                        if (!follows) {
                            start = currentline;
                            before(errors, expected, currentline,3, fmt);
                        }
                        bool preceeds = i+1 < linesKO.Count && linesKO[i+1] == currentline+1;
                        if (!preceeds) {
                            diff(errors, expected, actual, start, currentline, fmt);
                            after(errors, expected, currentline,3, fmt);
                            start = -1;
                        }
                    }
                    for(int i=actual.Count; i<expected.Count; i++)
                        errors.AppendLine(String.Format("-{0:"+fmt+"} {1}", i, expected[i]));
                    for(int i=expected.Count; i<actual.Count; i++)
                        errors.AppendLine(String.Format("+{0:"+fmt+"} {1}", i, actual[i]));
                    if (errors.Length > 0) {
                        codegenErrors += linesKO.Count + Math.Abs(actual.Count - expected.Count);
                        System.IO.File.AppendAllText("CheckGrammarResults.txt", errors.ToString());
                        if (okay) nbFilesInError++;
                    }
                }
            }
            string total = String.Format("{0:00}m{1:00}s{2:000}ms", sum.Minutes, sum.Seconds, sum.Milliseconds);
            string message = "Files tested=" + tested + "/" + files.Length + ", files in error=" + nbFilesInError + ", ignored=" + ignores + "\n";
            if (parseErrors > 0)   message += "Parsing errors: "+ parseErrors   + '\n';
            if (codegenErrors > 0) message += "Codegen errors: "+ codegenErrors + '\n';
            message += "Total time: " + total;
            System.IO.File.AppendAllText("CheckGrammarResults.txt", message);
            if (nbFilesInError > 0) Assert.Fail('\n'+message);
        }
Example #2
0
        private static void runOnce(Config config)
        {
            TextWriter w;
            if (config.ErrorFile == null) w = System.Console.Error;
            else w = File.CreateText(config.ErrorFile);
            AbstractErrorWriter writer;
            if (config.IsErrorXML) writer = new XMLWriter(w);
            else writer = new ConsoleWriter(w);
            writer.Outputs = config.OutputFiles;

            var parser = new Parser();
            parser.CustomSymbols = loadCopies(config.Copies);

            for(int c=0; c<config.InputFiles.Count; c++) {
                string path = config.InputFiles[c];
                try { parser.Init(path, config.Format); }
                catch(System.IO.IOException ex) {
                    AddError(writer, ex.Message, path);
                    continue;
                }
                parser.Parse(path);
                if (parser.Results.CodeElementsDocumentSnapshot == null) {
                    AddError(writer, "File \""+path+"\" has syntactic error(s) preventing codegen (CodeElements).", path);
                    continue;
                }

                writer.AddErrors(path, parser.Converter.AsDiagnostics(parser.Results.CodeElementsDocumentSnapshot.ParserDiagnostics));
                // no need to add errors from parser.CodeElementsSnapshot.CodeElements
                // as they are on parser.CodeElementsSnapshot.CodeElements which are added below

                if (parser.Results.ProgramClassDocumentSnapshot == null) {
                    AddError(writer, "File \""+path+"\" has semantic error(s) preventing codegen (ProgramClass).", path);
                    continue;
                }
                int errors = 0;
                errors += new List<Compiler.Diagnostics.Diagnostic>(parser.Results.CodeElementsDocumentSnapshot.ParserDiagnostics).Count;
                errors += parser.Results.ProgramClassDocumentSnapshot.Diagnostics.Count;
                writer.AddErrors(path, parser.Converter.AsDiagnostics(parser.Results.ProgramClassDocumentSnapshot.Diagnostics));
                foreach(var e in parser.Results.CodeElementsDocumentSnapshot.CodeElements) {
                    if (e.Diagnostics.Count < 1) continue;
                    errors += e.Diagnostics.Count;
                    writer.AddErrors(path, parser.Converter.GetDiagnostics(e));
                }

                if (config.Codegen && (errors == 0 || !config.Safe)) {
                    var skeletons = TypeCobol.Codegen.Config.Config.Parse(config.skeletonPath);
                    var codegen = new TypeCobol.Codegen.Generator(new StreamWriter(config.OutputFiles[c]), parser.Results.TokensLines, skeletons);
                    var program = parser.Results.ProgramClassDocumentSnapshot.Program;
                    codegen.Generate(program.SyntaxTree.Root, program.SymbolTable, ColumnsLayout.CobolReferenceFormat);
                }
            }
            writer.Write();
            writer.Flush();
        }