コード例 #1
0
        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);
                }
            }
        }
コード例 #2
0
        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());
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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)));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
ファイル: WorkflowTests.cs プロジェクト: ag-csharp/DAGE
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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")));
            }
        }
コード例 #14
0
        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);
        }