private static void Grammar25(int stopAtStep)
        {
            /* Leo */
            RGG grammar = new RGG("grammar (1)");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("A").Terminal("a").Or.NonTerminal("S").Terminal("a").Terminal("a").Or.TerminalEmpty.PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match original paper
            // Test input: Non-Match
        }
        private static void Grammar13(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("G3");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").Terminal("a").Terminal("b").Or.Terminal("a").NonTerminal("S").Terminal("b").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match number of a followed by same number of b fx aabb
            // Test input: Non-Match aaabb
        }
        private static void Grammar21(int stopAtStep)
        {
            /* An Improved Context-Free Recognizer */
            RGG grammar = new RGG("Example 2");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("S").Terminal("a").Or.Terminal("a").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match aaa
            // Test input: Non-Match
        }
        private static void Grammar10(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("PAL");

            grammar.BuildPattern("Start").NonTerminal("A").PatternEnd();
            grammar.BuildPattern("A").Terminal("x").Or.Terminal("x").NonTerminal("A").Terminal("x").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match Unequal number of X
            // Test input: Non-Match Equal number of x
        }
        private static void Grammar8(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("UBDA");

            grammar.BuildPattern("Start").NonTerminal("A").PatternEnd();
            grammar.BuildPattern("A").Terminal("x").Or.NonTerminal("A").NonTerminal("A").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match x, xx, xxxx
            // Test input: Non-Match xxx, xxxxx
        }
        private static void Grammar3(int stopAtStep)
        {
            /* Earley parser presentation */
            RGG grammar = new RGG("Worst case");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("S").NonTerminal("S").Or.Terminal("x").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match x, xx, xxxx
            // Test input: Non-Match xxx, xxxxx
        }
        private static void Grammar16(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("GRE");

            grammar.BuildPattern("Start").NonTerminal("X").PatternEnd();
            grammar.BuildPattern("X").Terminal("a").Or.NonTerminal("X").Terminal("b").Or.NonTerminal("Y").Terminal("a").PatternEnd();
            grammar.BuildPattern("Y").Terminal("e").Or.NonTerminal("Y").Terminal("d").NonTerminal("Y").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match original paper
            // Test input: Non-Match
        }
        private static void Grammar28(int stopAtStep)
        {
            /* Horspool/McLean */
            RGG grammar = new RGG("Horspool grammar");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("E").PatternEnd();
            grammar.BuildPattern("E").NonTerminal("E").Terminal("+").NonTerminal("E").Or.Terminal("n").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match original paper
            // Test input: Non-Match
        }
        private static void Grammar1(int stopAtStep)
        {
            /* Efficient Earley Parsing with Regular Right-hand Sides */
            RGG grammar = new RGG("Transducer example");

            grammar.BuildPattern("Start").Terminal("x").GroupStart.NonTerminal("A").Or.Terminal("y").NonTerminal("B").GroupEnd.PatternEnd();
            grammar.BuildPattern("A").Terminal("y").GroupStart.NonTerminal("B").Or.NonTerminal("C").GroupEnd.PatternEnd();
            grammar.BuildPattern("B").Terminal("w").Terminal("w").Terminal("w").PatternEnd();
            grammar.BuildPattern("C").Terminal("z").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match
            // Test input: Non-Match
        }
        private static void Grammar2(int stopAtStep)
        {
            /* Earley parser presentation */
            RGG grammar = new RGG("A calculus");

            grammar.BuildPattern("Start").NonTerminal("E").PatternEnd();
            grammar.BuildPattern("E").NonTerminal("E").NonTerminal("Q").NonTerminal("F").Or.NonTerminal("F").PatternEnd();
            grammar.BuildPattern("Q").Terminal("+").Or.Terminal("-").PatternEnd();
            grammar.BuildPattern("F").Terminal("a").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match a-a+a and a+a-a
            // Test input: Non-Match aa+a, a-aa and a--a+a
        }
        private static void Grammar14(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("G4");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("A").NonTerminal("B").PatternEnd();
            grammar.BuildPattern("A").Terminal("a").Or.NonTerminal("A").Terminal("b").PatternEnd();
            grammar.BuildPattern("B").Terminal("b").Terminal("c").Or.Terminal("b").NonTerminal("B").Or.NonTerminal("B").Terminal("d").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match a + number of b + cd
            // Test input: Non-Match abbbccd
        }
        private static void Grammar4(int stopAtStep)
        {
            /* Earley parser presentation */
            RGG grammar = new RGG("A calculus with empty");

            grammar.BuildPattern("Start").NonTerminal("E").PatternEnd();
            grammar.BuildPattern("E").NonTerminal("E").NonTerminal("Q").NonTerminal("F").Or.NonTerminal("F").PatternEnd();
            grammar.BuildPattern("Q").Terminal("*").Or.Terminal("/").Or.TerminalEmpty.PatternEnd();
            grammar.BuildPattern("F").Terminal("a").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match aa/a, aa*a, a/aa and a/a*a
            // Test input: Non-Match a**a/a
        }
        private static void Grammar5(int stopAtStep)
        {
            /* Earley parser explained */
            RGG grammar = new RGG("EBNF");

            grammar.BuildPattern("Start").NonTerminal("Sum").PatternEnd();
            grammar.BuildPattern("Sum").NonTerminal("Sum").GroupStart.Terminal("+").Or.Terminal("-").GroupEnd.NonTerminal("Product").Or.NonTerminal("Product").PatternEnd();
            grammar.BuildPattern("Product").NonTerminal("Product").GroupStart.Terminal("*").Or.Terminal("/").GroupEnd.NonTerminal("Factor").Or.NonTerminal("Factor").PatternEnd();
            grammar.BuildPattern("Factor").Terminal("(").NonTerminal("Sum").Terminal(")").Or.NonTerminal("Number").PatternEnd();
            grammar.BuildPattern("Number").Terminal("[0-9]+").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match 1+(2*4-4)
            // Test input: Non-Match
        }
        private static void Grammar27(int stopAtStep)
        {
            /* Leo */
            int i       = 3;
            RGG grammar = new RGG("Leo grammar");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("R1").NonTerminal("S").Or.NonTerminal("R2").NonTerminal("S").Or.TerminalEmpty.PatternEnd();
            grammar.BuildPattern("R1").Terminal("x").NonTerminal("R1").Terminal("d").RepeatNext(0, i).Terminal("c").PatternEnd();
            grammar.BuildPattern("R2").Terminal("y").NonTerminal("R2").Terminal("d").Terminal("c").RepeatPrevious(0, i).PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match original paper
            // Test input: Non-Match
        }
        public void FullPattern_Terminal(string grammarName, string patternName, string terminalName)
        {
            RGG rGG = new RGG(grammarName);

            rGG.BuildPattern(patternName).Terminal(terminalName).PatternEnd();
            rGG.BuildGraph(1);
            RGGNode startPatternNode = rGG.GetPatternStart(patternName);

            Assert.Equal(1, startPatternNode.TransitionCount);
            // Pattern Start
            RGGTransition candidateTransition = startPatternNode.Transitions.First();

            Assert.Equal(TransitionType.PatternStart, candidateTransition.TransitionType);
            RGGNode candidateNode = candidateTransition.To;

            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // Terminal
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.Terminal, candidateTransition.TransitionType);
            Assert.Equal(terminalName, candidateTransition.Terminal.ToString());
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // Pattern End
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.PatternEnd, candidateTransition.TransitionType);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(0, candidateNode.TransitionCount);
        }
        public void EndPatternBuilder(string grammarName, string patternName, string terminalName)
        {
            Exception expected = null;
            Exception actual   = null;
            RGG       rGG      = new RGG(grammarName);

            try
            {
                rGG.BuildPattern(patternName).Terminal(terminalName).PatternEnd();
            }
            catch (Exception ex)
            {
                actual = ex;
            }
            Assert.Equal(expected, actual);
        }
        public void PartialPatternBuilder_Terminal(string grammarName, string patternName, string terminalName)
        {
            Exception    expected = null;
            Exception    actual   = null;
            RGG          rGG      = new RGG(grammarName);
            IPatternPart patternPart;

            try
            {
                patternPart = rGG.BuildPattern(patternName).Terminal(terminalName);
            }
            catch (Exception ex)
            {
                actual = ex;
            }
            Assert.Equal(expected, actual);
        }
        public void CreatePatternBuilder(string grammarName, string patternName)
        {
            Exception         expected = null;
            Exception         actual   = null;
            RGG               rGG      = new RGG(grammarName);
            IStartPatternPart patternPart;

            try
            {
                patternPart = rGG.BuildPattern(patternName);
            }
            catch (Exception ex)
            {
                actual = ex;
            }
            Assert.Equal(expected, actual);
        }
        public void FullPattern_RepeatPrevious_GroupStart_Terminal(string grammarName, string patternName, string terminalName)
        {
            RGG rGG = new RGG(grammarName);

            rGG.BuildPattern(patternName).GroupStart.Terminal(terminalName).GroupEnd.RepeatPrevious(0, 3).PatternEnd();
            rGG.BuildGraph(1);
            RGGNode startPatternNode = rGG.GetPatternStart(patternName);

            Assert.Equal(1, startPatternNode.TransitionCount);
            // Pattern Start
            RGGTransition candidateTransition = startPatternNode.Transitions.First();

            Assert.Equal(TransitionType.PatternStart, candidateTransition.TransitionType);
            RGGNode candidateNode = candidateTransition.To;

            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // GroupStart
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.GroupStart, candidateTransition.TransitionType);
            Assert.Equal(Constants.UnnamedGroupStart, candidateTransition.Internal);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // Terminal
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.Terminal, candidateTransition.TransitionType);
            Assert.Equal(terminalName, candidateTransition.Terminal.ToString());
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // GroupEnd
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.GroupEnd, candidateTransition.TransitionType);
            Assert.Equal(string.Format(Constants.EndPattern, Constants.UnnamedGroupStart), candidateTransition.Internal);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // Pattern End
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.PatternEnd, candidateTransition.TransitionType);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(0, candidateNode.TransitionCount);
        }
        private static void Grammar15(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("Propositional Calculus Grammar");

            grammar.BuildPattern("Start").NonTerminal("F").PatternEnd();
            grammar.BuildPattern("F").NonTerminal("C").Or.NonTerminal("S").Or.NonTerminal("P").Or.NonTerminal("U").PatternEnd();
            grammar.BuildPattern("C").NonTerminal("U").Terminal("⊃").NonTerminal("U").PatternEnd();
            grammar.BuildPattern("U").Terminal("(").NonTerminal("F").Terminal(")").Or.Terminal("~").NonTerminal("U").Or.NonTerminal("L").PatternEnd();
            grammar.BuildPattern("L").NonTerminal("L").Terminal("'").Or.Terminal("p").Or.Terminal("q").Or.Terminal("r").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("U").Terminal("∨").NonTerminal("S").Or.NonTerminal("U").Terminal("∨").NonTerminal("U").PatternEnd();
            grammar.BuildPattern("P").NonTerminal("U").Terminal("∧").NonTerminal("P").Or.NonTerminal("U").Terminal("∧").NonTerminal("U").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match original paper
            // Test input: Non-Match
        }
        private static void Grammar7(int stopAtStep)
        {
            /* An Efficient Context-Free Parsing Algorithm */
            RGG grammar = new RGG("AE");

            grammar.BuildPattern("Start").NonTerminal("E").PatternEnd();
            grammar.BuildPattern("E").NonTerminal("T").PatternEnd();
            grammar.BuildPattern("E").NonTerminal("E").Terminal("+").NonTerminal("T").PatternEnd();
            grammar.BuildPattern("T").NonTerminal("P").PatternEnd();
            grammar.BuildPattern("T").NonTerminal("T").Terminal("*").NonTerminal("P").PatternEnd();
            grammar.BuildPattern("P").Terminal("a").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match a+a*a
            // Test input: Non-Match
        }
        private static void Grammar18(int stopAtStep)
        {
            /* An Improved Context-Free Recognizer */
            RGG grammar = new RGG("Example Empty Rules");

            grammar.BuildPattern("Start").NonTerminal("S").PatternEnd();
            grammar.BuildPattern("S").NonTerminal("A").NonTerminal("B").NonTerminal("A").NonTerminal("C").PatternEnd();
            grammar.BuildPattern("A").TerminalEmpty.PatternEnd();
            grammar.BuildPattern("B").NonTerminal("C").NonTerminal("D").NonTerminal("C").PatternEnd();
            grammar.BuildPattern("C").TerminalEmpty.PatternEnd();
            grammar.BuildPattern("D").Terminal("a").PatternEnd();
            grammar.BuildGraph(stopAtStep);
            grammar.PrintRGG(string.Format("Step {0}", stopAtStep), "Start");
            // Test input: Match original paper
            // Test input: Non-Match
        }
        public void FullPattern_Or(string grammarName, string patternName, string terminalName1, string terminalName2)
        {
            RGG rGG = new RGG(grammarName);

            rGG.BuildPattern(patternName).Terminal(terminalName1).Or.Terminal(terminalName2).PatternEnd();
            rGG.BuildGraph(1);
            RGGNode startPatternNode = rGG.GetPatternStart(patternName);

            Assert.Equal(2, startPatternNode.TransitionCount);
            int counter = 0;

            foreach (RGGTransition startTransition in startPatternNode.Transitions)
            {
                // Pattern Start
                RGGTransition candidateTransition = startTransition;
                Assert.Equal(TransitionType.PatternStart, candidateTransition.TransitionType);
                RGGNode candidateNode = candidateTransition.To;
                Assert.True(candidateNode.Name.StartsWith(patternName));
                Assert.Equal(1, candidateNode.TransitionCount);
                // Terminal
                candidateTransition = candidateNode.Transitions.First();
                Assert.Equal(TransitionType.Terminal, candidateTransition.TransitionType);
                Assert.Equal(counter == 0?terminalName1:terminalName2, candidateTransition.Terminal.ToString());
                candidateNode = candidateTransition.To;
                Assert.True(candidateNode.Name.StartsWith(patternName));
                Assert.Equal(1, candidateNode.TransitionCount);
                // Pattern End
                candidateTransition = candidateNode.Transitions.First();
                Assert.Equal(TransitionType.PatternEnd, candidateTransition.TransitionType);
                candidateNode = candidateTransition.To;
                Assert.True(candidateNode.Name.StartsWith(patternName));
                Assert.Equal(0, candidateNode.TransitionCount);

                counter += 1;
            }
        }
        public void FullPattern_NamedGroupStart_Or2(string grammarName, string patternName, string groupName, string terminalName1, string terminalName2, string terminalName3, string terminalName4)
        {
            RGG rGG = new RGG(grammarName);

            rGG.BuildPattern(patternName).NamedGroupStart(groupName).Terminal(terminalName1).Terminal(terminalName2).Or.Terminal(terminalName3).Terminal(terminalName4).GroupEnd.PatternEnd();
            rGG.BuildGraph(1);
            RGGNode startPatternNode = rGG.GetPatternStart(patternName);

            Assert.Equal(1, startPatternNode.TransitionCount);
            // Pattern Start
            RGGTransition candidateTransition = startPatternNode.Transitions.First();

            Assert.Equal(TransitionType.PatternStart, candidateTransition.TransitionType);
            RGGNode candidateNode = candidateTransition.To;

            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // NamedGroupStart
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.GroupStart, candidateTransition.TransitionType);
            Assert.Equal(groupName, candidateTransition.Internal);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(2, candidateNode.TransitionCount);
            int    counter  = 0;
            string nextName = string.Empty;

            foreach (RGGTransition groupStartTransition in candidateNode.Transitions)
            {
                // Terminal
                candidateTransition = groupStartTransition;
                Assert.Equal(TransitionType.Terminal, candidateTransition.TransitionType);
                Assert.Equal(counter == 0 ? terminalName1 : terminalName3, candidateTransition.Terminal.ToString());
                candidateNode = candidateTransition.To;
                Assert.True(candidateNode.Name.StartsWith(patternName));
                Assert.Equal(1, candidateNode.TransitionCount);
                // Terminal
                candidateTransition = candidateNode.Transitions.First();;
                Assert.Equal(TransitionType.Terminal, candidateTransition.TransitionType);
                Assert.Equal(counter == 0 ? terminalName2 : terminalName4, candidateTransition.Terminal.ToString());
                candidateNode = candidateTransition.To;
                Assert.True(candidateNode.Name.StartsWith(patternName));
                Assert.Equal(1, candidateNode.TransitionCount);
                if (nextName == string.Empty)
                {
                    nextName = candidateNode.Name;
                }
                else
                {
                    Assert.Equal(nextName, candidateNode.Name);
                }

                counter += 1;
            }
            // GroupEnd
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.GroupEnd, candidateTransition.TransitionType);
            Assert.Equal(string.Format(Constants.EndPattern, groupName), candidateTransition.Internal);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(1, candidateNode.TransitionCount);
            // Pattern End
            candidateTransition = candidateNode.Transitions.First();
            Assert.Equal(TransitionType.PatternEnd, candidateTransition.TransitionType);
            candidateNode = candidateTransition.To;
            Assert.True(candidateNode.Name.StartsWith(patternName));
            Assert.Equal(0, candidateNode.TransitionCount);
        }