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); }
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(); }