public void SeparatedLexerAndParserErrors() { var lexerText = $@"lexer grammar {TestGrammarName}; CHAR: a-z]+; DIGIT: [0-9]+; WS: [ \r\n\t]+ -> skip;"; var parserText = $@"parser grammar {TestGrammarName}; start: DIGIT+; #"; var workflow = new Workflow(GrammarFactory.CreateDefaultSeparatedAndFill(lexerText, parserText, TestGrammarName, ".")); var state = workflow.Process(); Assert.AreEqual(WorkflowStage.GrammarChecked, state.Stage, state.Exception?.ToString()); var testLexerSource = new CodeSource(TestGrammarName + "Lexer.g4", File.ReadAllText(TestGrammarName + "Lexer.g4")); var testParserSource = new CodeSource(TestGrammarName + "Parser.g4", File.ReadAllText(TestGrammarName + "Parser.g4")); GrammarCheckedState grammarCheckedState = state as GrammarCheckedState; CollectionAssert.AreEquivalent( new [] { new ParsingError(2, 25, $"error: {TestGrammarName}Lexer.g4:2:25: token recognition error at: '-z'", testLexerSource, WorkflowStage.GrammarChecked), new ParsingError(2, 27, $"error: {TestGrammarName}Lexer.g4:2:27: token recognition error at: ']'", testLexerSource, WorkflowStage.GrammarChecked), new ParsingError(2, 28, $"error: {TestGrammarName}Lexer.g4:2:28: mismatched input '+' expecting {{ASSIGN, PLUS_ASSIGN}}", testLexerSource, WorkflowStage.GrammarChecked), new ParsingError(3, 16, $"error: {TestGrammarName}Parser.g4:3:16: extraneous input '#' expecting {{<EOF>, 'mode'}}", testParserSource, WorkflowStage.GrammarChecked) }, grammarCheckedState.Errors); }
public GrammarCheckedState Check(InputState inputState, CancellationToken cancellationToken = default) { var grammar = inputState.Grammar; _result = new GrammarCheckedState(inputState); try { var antlrErrorListener = new AntlrErrorListener(); antlrErrorListener.ErrorEvent += ErrorEvent; antlrErrorListener.ErrorEvent += (sender, error) => { lock (_result.Errors) { _result.Errors.Add(error); } }; foreach (string grammarFileName in grammar.Files) { ProcessGrammarFile(grammar, grammarFileName, antlrErrorListener, cancellationToken); } } catch (Exception ex) { _result.Exception = ex; if (!(ex is OperationCanceledException)) { ErrorEvent?.Invoke(this, new ParsingError(ex, WorkflowStage.GrammarChecked)); } } return(_result); }
private void GetGeneratedFileNames(GrammarCheckedState grammarCheckedState, string generatedGrammarName, string workingDirectory, List <string> generatedFiles, bool lexer) { string grammarNameExt; if (_grammar.Type == GrammarType.Combined) { grammarNameExt = _grammar.Files.FirstOrDefault(file => Path.GetExtension(file) .Equals(Grammar.AntlrDotExt, StringComparison.OrdinalIgnoreCase)); } else { string postfix = lexer ? Grammar.LexerPostfix : Grammar.ParserPostfix; grammarNameExt = _grammar.Files.FirstOrDefault(file => file.Contains(postfix) && Path.GetExtension(file).Equals(Grammar.AntlrDotExt, StringComparison.OrdinalIgnoreCase)); } string shortGeneratedFile = generatedGrammarName + (lexer ? _currentRuntimeInfo.LexerPostfix : _currentRuntimeInfo.ParserPostfix) + "." + _currentRuntimeInfo.Extensions[0]; string generatedFileDir = workingDirectory; Runtime runtime = _currentRuntimeInfo.Runtime; if ((runtime == Runtime.Java || runtime == Runtime.Go) && !string.IsNullOrWhiteSpace(_result.ParserGeneratedState.PackageName)) { generatedFileDir = Path.Combine(generatedFileDir, _result.ParserGeneratedState.PackageName); } string generatedFile = Path.Combine(generatedFileDir, shortGeneratedFile); generatedFiles.Add(generatedFile); CodeSource codeSource = new CodeSource(generatedFile, File.ReadAllText(generatedFile)); _grammarCodeMapping[shortGeneratedFile] = TextHelpers.Map(grammarCheckedState.GrammarActionsTextSpan[grammarNameExt], codeSource, lexer); }
public ParserGeneratedState Generate(GrammarCheckedState state, CancellationToken cancellationToken = default) { Grammar grammar = state.InputState.Grammar; _result = new ParserGeneratedState(state, PackageName, Runtime, GenerateListener, GenerateVisitor); Generate(grammar, state, cancellationToken); return(_result); }
public void GrammarCheckedStageErrors() { var grammarText = $@"grammar {TestGrammarName}; start: DIGIT+; CHAR: a-z]+; DIGIT: [0-9]+; WS: [ \r\n\t]+ -> skip;"; var workflow = new Workflow(GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, ".")); var state = workflow.Process(); Assert.AreEqual(WorkflowStage.GrammarChecked, state.Stage, state.Exception?.ToString()); var grammarSource = new CodeSource(TestGrammarName + ".g4", File.ReadAllText(TestGrammarName + ".g4")); GrammarCheckedState grammarCheckedState = state as GrammarCheckedState; CollectionAssert.AreEquivalent( new [] { new ParsingError(3, 25, "error: test.g4:3:25: token recognition error at: '-z'", grammarSource, WorkflowStage.GrammarChecked), new ParsingError(3, 27, "error: test.g4:3:27: token recognition error at: ']'", grammarSource, WorkflowStage.GrammarChecked), new ParsingError(3, 28, "error: test.g4:3:28: mismatched input '+' expecting {ASSIGN, PLUS_ASSIGN}", grammarSource, WorkflowStage.GrammarChecked) }, grammarCheckedState.Errors); }
private void Generate(Grammar grammar, GrammarCheckedState state, CancellationToken cancellationToken) { Processor processor = null; try { string runtimeDirectoryName = Path.Combine(HelperDirectoryName, grammar.Name, Runtime.ToString()); if ((Runtime == Runtime.Java || Runtime == Runtime.Go) && !string.IsNullOrWhiteSpace(PackageName)) { runtimeDirectoryName = Path.Combine(runtimeDirectoryName, PackageName); } if (Directory.Exists(runtimeDirectoryName)) { Directory.Delete(runtimeDirectoryName, true); } Directory.CreateDirectory(runtimeDirectoryName); cancellationToken.ThrowIfCancellationRequested(); RuntimeInfo runtimeInfo = RuntimeInfo.InitOrGetRuntimeInfo(Runtime); var jarGenerator = GeneratorTool ?? Path.Combine("Generators", runtimeInfo.JarGenerator); foreach (string grammarFileName in state.InputState.Grammar.Files) { string extension = Path.GetExtension(grammarFileName); if (extension != Grammar.AntlrDotExt) { continue; } _currentGrammarSource = state.GrammarFilesData[grammarFileName]; var arguments = $@"-jar ""{jarGenerator}"" ""{Path.Combine(grammar.Directory, grammarFileName)}"" " + $@"-o ""{runtimeDirectoryName}"" " + $"-Dlanguage={runtimeInfo.DLanguage} " + $"{(GenerateVisitor ? "-visitor" : "-no-visitor")} " + $"{(GenerateListener ? "-listener" : "-no-listener")}"; if (!string.IsNullOrWhiteSpace(PackageName)) { arguments += " -package " + PackageName; } else if (Runtime == Runtime.Go) { arguments += " -package main"; } if (grammarFileName.Contains(Grammar.LexerPostfix) && state.LexerSuperClass != null) { arguments += " -DsuperClass=" + state.LexerSuperClass; } if (grammarFileName.Contains(Grammar.ParserPostfix) && state.ParserSuperClass != null) { arguments += " -DsuperClass=" + state.ParserSuperClass; } _result.Command = "java " + arguments; processor = new Processor("java", arguments, "."); processor.CancellationToken = cancellationToken; processor.ErrorDataReceived += ParserGeneration_ErrorDataReceived; processor.OutputDataReceived += ParserGeneration_OutputDataReceived; processor.Start(); cancellationToken.ThrowIfCancellationRequested(); } } catch (Exception ex) { _result.Exception = ex; if (!(ex is OperationCanceledException)) { ErrorEvent?.Invoke(this, new ParsingError(ex, WorkflowStage.ParserGenerated)); } } finally { processor?.Dispose(); } }