public void AllGeneratorsExists() { var runtimes = (Runtime[])Enum.GetValues(typeof(Runtime)); 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, ".")); workflow.EndStage = WorkflowStage.ParserGenerated; foreach (Runtime runtime in runtimes) { workflow.Runtime = runtime; var state = (ParserGeneratedState)workflow.Process(); Assert.IsFalse(state.HasErrors, string.Join(Environment.NewLine, state.Errors)); RuntimeInfo runtimeInfo = RuntimeInfo.Runtimes[runtime]; var extensions = runtimeInfo.Extensions; var allFiles = Directory.GetFiles(Path.Combine(ParserGenerator.HelperDirectoryName, TestGrammarName, runtimeInfo.Runtime.ToString())); var actualFilesCount = allFiles.Count(file => extensions.Any(ext => Path.GetExtension(file).EndsWith(ext))); Assert.Greater(actualFilesCount, 0, $"Failed to initialize {runtime} runtime"); foreach (var file in allFiles) { File.Delete(file); } } }
public void GrammarGeneratedCodeCorrectMapping(Runtime runtime) { Assert.Ignore("Not ready"); var grammarText = @"grammar test; rootRule : {a==0}? tokensOrRules* EOF {a++;} ; tokensOrRules : {a==0}? TOKEN+ {a++;} ; TOKEN: {b==0}? [a-z]+ {b++;}; DIGIT: {b==0}? [0-9]+ {b++;};"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, "test", "."); var workflow = new Workflow(grammar); workflow.Runtime = runtime; var state = workflow.Process(); Assert.AreEqual(WorkflowStage.ParserCompiled, state.Stage, state.Exception?.ToString()); ParserCompiledState parserGeneratedState = state as ParserCompiledState; var errors = parserGeneratedState.Errors; Assert.AreEqual(8, errors.Count); Assert.AreEqual(2, errors.Where(e => e.TextSpan.GetLineColumn().BeginLine == 3).Count()); Assert.AreEqual(2, errors.Where(e => e.TextSpan.GetLineColumn().BeginLine == 6).Count()); Assert.AreEqual(2, errors.Where(e => e.TextSpan.GetLineColumn().BeginLine == 8).Count()); Assert.AreEqual(2, errors.Where(e => e.TextSpan.GetLineColumn().BeginLine == 9).Count()); }
public void CheckCustomRoot(Runtime runtime) { var grammarText = $"grammar {TestGrammarName};" + "root1: 'V1';" + "root2: 'V2';"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); var workflow = new Workflow(grammar); workflow.Runtime = runtime; workflow.TextFileName = TestTextName; workflow.Root = null; File.WriteAllText(TestTextName, "V1"); var state = workflow.Process(); TextParsedState textParsedState = state as TextParsedState; Assert.IsNotNull(textParsedState); Assert.IsFalse(state.HasErrors); workflow.Root = "root1"; state = workflow.Process(); textParsedState = state as TextParsedState; Assert.IsNotNull(textParsedState); Assert.IsFalse(state.HasErrors); workflow.Root = "root2"; File.WriteAllText(TestTextName, "V2"); state = workflow.Process(); textParsedState = state as TextParsedState; Assert.IsNotNull(textParsedState); Assert.IsFalse(state.HasErrors); }
public void CheckPackageName(Runtime runtime) { const string packageName = "TestLanguage"; var grammarText = $@"grammar {TestGrammarName}; root: TOKEN; TOKEN: 'a';"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); grammar.CaseInsensitiveType = CaseInsensitiveType.lower; var workflow = new Workflow(grammar) { Runtime = runtime, PackageName = packageName, TextFileName = TestTextName }; File.WriteAllText(TestTextName, "A"); var state = workflow.Process(); var textParsedState = state as TextParsedState; Assert.IsNotNull(textParsedState); Assert.IsFalse(textParsedState.HasErrors); }
private static void CheckCaseInsensitiveWorkflow(Runtime runtime, bool lowerCase) { char c = lowerCase ? 'a' : 'A'; var grammarText = $@"grammar {TestGrammarName}; start: A A DIGIT; A: '{c}'; DIGIT: [0-9]+; WS: [ \r\n\t]+ -> skip;"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); grammar.CaseInsensitiveType = lowerCase ? CaseInsensitiveType.lower : CaseInsensitiveType.UPPER; File.WriteAllText(TestTextName, @"A a 1234"); var workflow = new Workflow(grammar); workflow.Runtime = runtime; workflow.TextFileName = TestTextName; var state = workflow.Process(); Assert.AreEqual(WorkflowStage.TextParsed, state.Stage, state.Exception?.ToString()); TextParsedState textParsedState = state as TextParsedState; Assert.AreEqual(0, textParsedState.Errors.Count, string.Join(Environment.NewLine, textParsedState.Errors)); Assert.AreEqual("(start A a 1234)", textParsedState.Tree); }
public void CheckListenersAndVisitors(Runtime runtime) { var grammarText = $@"grammar {TestGrammarName}; t: T; T: [a-z]+;"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); File.WriteAllText(TestTextName, @"asdf"); var workflow = new Workflow(grammar) { GenerateListener = true, GenerateVisitor = true }; workflow.Runtime = runtime; workflow.TextFileName = TestTextName; var state = workflow.Process(); TextParsedState textParsedState = state as TextParsedState; Assert.IsNotNull(textParsedState); Assert.IsFalse(state.HasErrors); var allFiles = Directory.GetFiles(Path.Combine(ParserGenerator.HelperDirectoryName, TestGrammarName, runtime.ToString())); Assert.IsTrue(allFiles.Any(file => file.Contains("listener", StringComparison.OrdinalIgnoreCase))); Assert.IsTrue(allFiles.Any(file => file.Contains("visitor", StringComparison.OrdinalIgnoreCase))); }
public void ParserGeneratedStageErrors() { var grammarText = $@"grammar {TestGrammarName}; start: rule1+; rule: 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.ParserGenerated, state.Stage, state.Exception?.ToString()); var grammarSource = new CodeSource(TestGrammarName + ".g4", File.ReadAllText(TestGrammarName + ".g4")); char separator = Path.DirectorySeparatorChar; string testGrammarFullName = $"{Environment.CurrentDirectory}{separator}.{separator}{TestGrammarName}.g4"; ParserGeneratedState parserGeneratedState = state as ParserGeneratedState; string str = new ParsingError(2, 24, $"error(56): {testGrammarFullName}:2:24: reference to undefined rule: rule1", grammarSource, WorkflowStage.ParserGenerated).ToString(); CollectionAssert.AreEquivalent( new [] { new ParsingError(2, 24, $"error(56): {testGrammarFullName}:2:24: reference to undefined rule: rule1", grammarSource, WorkflowStage.ParserGenerated), }, parserGeneratedState.Errors); }
public void TextParsedStageErrors(Runtime runtime) { var grammarText = $@"grammar {TestGrammarName}; start: DIGIT+; CHAR: [a-z]+; DIGIT: [0-9]+; WS: [ \r\n\t]+ -> skip;"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); File.WriteAllText(TestTextName, @"! asdf 1234"); var workflow = new Workflow(grammar); workflow.Runtime = runtime; workflow.TextFileName = TestTextName; var state = workflow.Process(); Assert.AreEqual(WorkflowStage.TextParsed, state.Stage, state.Exception?.ToString()); TextParsedState textParsedState = state as TextParsedState; var textSource = textParsedState.Text; CollectionAssert.AreEquivalent( new [] { new ParsingError(1, 1, "line 1:0 token recognition error at: '!'", textSource, WorkflowStage.TextParsed), new ParsingError(1, 4, "line 1:3 extraneous input 'asdf' expecting DIGIT", textSource, WorkflowStage.TextParsed) }, textParsedState.Errors); Assert.AreEqual("(start asdf 1234)", textParsedState.Tree); }
public void CheckPredictionMode(Runtime runtime) { var grammarText = $@" grammar {TestGrammarName}; root : (stmt1 | stmt2) EOF ; stmt1 : name ; stmt2 : 'static' name '.' Id ; name : Id ('.' Id)* ; Dot : '.'; Static : 'static'; Id : [A-Za-z]+; Whitespace : [ \t\r\n]+ -> channel(HIDDEN); "; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); var workflow = new Workflow(grammar); workflow.Runtime = runtime; workflow.TextFileName = TestTextName; File.WriteAllText(TestTextName, @"static a.b"); workflow.PredictionMode = PredictionMode.LL; var llState = workflow.Process(); TextParsedState llTextParsedState = llState as TextParsedState; Assert.IsNotNull(llTextParsedState); Assert.IsFalse(llState.HasErrors); workflow.PredictionMode = PredictionMode.SLL; var sllState = workflow.Process(); var sllTextParsedState = sllState as TextParsedState; Assert.IsNotNull(sllTextParsedState); Assert.IsTrue(sllTextParsedState.HasErrors); }
public void DoNotStopProcessingIfWarnings() { var grammarText = $@"grammar {TestGrammarName}; t: T; T: ['' ]+;"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); File.WriteAllText(TestTextName, " "); var workflow = new Workflow(grammar); workflow.Runtime = Runtime.Java; workflow.TextFileName = TestTextName; var state = workflow.Process(); Assert.AreEqual(WorkflowStage.TextParsed, state.Stage); Assert.IsTrue(((TextParsedState)state).ParserCompiledState.ParserGeneratedState.Errors[0].IsWarning); }
public void ParserCompiledStageErrors(Runtime runtime) { var grammarText = @"grammar Test; start: DIGIT+ {i^;}; CHAR: [a-z]+; DIGIT: [0-9]+; WS: [ \r\n\t]+ -> skip;"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, "Test", "."); var workflow = new Workflow(grammar); workflow.Runtime = runtime; var state = workflow.Process(); Assert.AreEqual(WorkflowStage.ParserCompiled, state.Stage, state.Exception?.ToString()); ParserCompiledState parserGeneratedState = state as ParserCompiledState; Assert.GreaterOrEqual(parserGeneratedState.Errors.Count, 1); //Assert.AreEqual(runtime == Runtime.Go ? 1 : 2, parserGeneratedState.Errors[0].TextSpan.GetLineColumn().BeginLine); }
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); }
public void CheckIncorrectGrammarDefinedOptions() { var grammarText = @$ "grammar {TestGrammarName}; // caseInsensitiveType=incorrect; // language=incorrect; // package=incorrect; // visitor=incorrect; // listener=incorrect; // root=incorrect; // predictionMode=incorrect; // caseInsensitiveType=lower; // language=JavaScript; // package=package; // visitor=true; // listener=true; // root=root; // predictionMode=sll; root: .*? ; TOKEN: 'token';"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); var workflow = new Workflow(grammar); workflow.TextFileName = TestTextName; workflow.EndStage = WorkflowStage.GrammarChecked; var state = (GrammarCheckedState)workflow.Process(); Assert.AreEqual(CaseInsensitiveType.lower, state.CaseInsensitiveType); Assert.AreEqual(Runtime.JavaScript, state.Runtime); Assert.AreEqual("package", state.Package); Assert.AreEqual(true, state.Listener); Assert.AreEqual(true, state.Visitor); Assert.AreEqual("root", state.Root); Assert.AreEqual(PredictionMode.SLL, state.PredictionMode); CheckIncorrect("caseInsensitiveType"); CheckIncorrect("language"); CheckIncorrect("package", true); CheckIncorrect("visitor"); CheckIncorrect("listener"); CheckIncorrect("root"); CheckIncorrect("predictionMode"); void CheckIncorrect(string optionName, bool notError = false) { bool Checker(ParsingError error) => error.Message.Contains(optionName != "root" ? $"Incorrect option {optionName}" : "Root incorrect is not exist"); if (!notError) { Assert.IsTrue(state.Errors.Any(Checker)); } else { Assert.IsFalse(state.Errors.Any(Checker)); } } CheckDuplication("caseInsensitiveType"); CheckDuplication("language"); CheckDuplication("package"); CheckDuplication("visitor"); CheckDuplication("listener"); CheckDuplication("root"); CheckDuplication("predictionMode"); void CheckDuplication(string optionName) { Assert.IsTrue(state.Errors.Any(error => error.Message.Contains($"Option {optionName} is already defined"))); } }
public void TextParsedStageErrors(Runtime runtime) { var grammarText = $@"grammar {TestGrammarName}; root : missingToken extraneousToken noViableAlternative mismatchedInput EOF ; missingToken : Error LParen RParen Semi ; extraneousToken : Error Id Semi ; mismatchedInput : Error Id Semi ; noViableAlternative : AA BB | AA CC ; AA: 'aa'; BB: 'bb'; CC: 'cc'; DD: 'dd'; LParen : '(('; RParen : '))'; Semi : ';'; Error : 'error'; Id : [A-Za-z][A-Za-z0-9]+; Whitespace : [ \t\r\n]+ -> channel(HIDDEN); Comment : '//' ~[\r\n]* -> channel(HIDDEN); Number : [0-9']+;"; var grammar = GrammarFactory.CreateDefaultCombinedAndFill(grammarText, TestGrammarName, "."); File.WriteAllText(TestTextName, @"# // token recognition error at: '#' error (( ; // missing '))' at ';' error id1 id2 ; // extraneous input 'id2' expecting ';' aa dd // no viable alternative at input 'aa dd' error 123 456 ; // mismatched input '123' expecting Id"); var workflow = new Workflow(grammar) { Runtime = runtime, TextFileName = TestTextName }; var state = workflow.Process(); Assert.AreEqual(WorkflowStage.TextParsed, state.Stage, state.Exception?.ToString()); TextParsedState textParsedState = (TextParsedState)state; var textSource = textParsedState.Text; CollectionAssert.AreEquivalent( new [] { new ParsingError(1, 1, 1, 2, "line 1:0 token recognition error at: '#'", textSource, WorkflowStage.TextParsed), new ParsingError(2, 10, 2, 11, "line 2:9 missing '))' at ';'", textSource, WorkflowStage.TextParsed), new ParsingError(3, 11, 3, 14, "line 3:10 extraneous input 'id2' expecting ';'", textSource, WorkflowStage.TextParsed), new ParsingError(4, 5, 4, 7, "line 4:4 no viable alternative at input 'aa dd'", textSource, WorkflowStage.TextParsed), new ParsingError(5, 7, 5, 10, "line 5:6 mismatched input '123' expecting Id", textSource, WorkflowStage.TextParsed) }, textParsedState.Errors); // TODO: unify in different runtimes //Assert.AreEqual("(root (missingToken error (( <missing '))'> ;) (extraneousToken error id1 id2 ;) (noViableAlternative aa dd) (mismatchedInput error 123 456 ;) EOF)", textParsedState.Tree); }