示例#1
0
        public void DeadStatesTest()
        {
            var dfa = new Dfa <string>();

            dfa.AddEdge(0, "A", 3);
            dfa.AddEdge(1, "B", 3);
            dfa.AddEdge(2, "C", 3);
            dfa.AddEdge(0, "E", 1);
            dfa.AddEdge(1, "E", 2);

            dfa.AddBadState(3);

            var emptyDfa = new Dfa <string>();

            var rules = new Dictionary <string, IDfa <Optional <Rule <string> >, string> >
            {
                ["A"] = dfa,
                ["E"] = emptyDfa
            };

            var grammar = new CompiledGrammar <string> {
                Rules = rules
            };

            var nullables = new List <DfaAndState <string> >
            {
                new DfaAndState <string> {
                    Dfa = emptyDfa, State = new ValueState <int>(0)
                }
            };

            var firstSymbols = FirstHelper <string> .GetFirstSymbols(grammar, nullables);

            var expected = new[]
            {
                "E",
                "E",
                string.Empty,
                string.Empty
            };

            for (int i = 0; i < 4; ++i)
            {
                var stateEntity = new DfaAndState <string> {
                    Dfa = dfa, State = new ValueState <int>(i)
                };
                string output = string.Join(',', firstSymbols[stateEntity].OrderBy(x => x));
                Assert.AreEqual(expected[i], output, $"Unexpected output on test {i}: expected is [{expected[i]}], but found [{output}]");
            }
        }
示例#2
0
        public void ThreeDfasTest()
        {
            var firstDfa = new Dfa <string>();

            firstDfa.AddEdge(0, "D", 1);
            firstDfa.AddEdge(0, "F", 4);
            firstDfa.AddEdge(0, "C", 3);
            firstDfa.AddEdge(0, "B", 2);
            firstDfa.AddEdge(2, "B", 7);
            firstDfa.AddEdge(3, "A", 5);
            firstDfa.AddEdge(4, "G", 6);
            firstDfa.AddEdge(6, "A", 5);

            var secondDfa = new Dfa <string>();

            secondDfa.AddEdge(0, "B", 1);
            secondDfa.AddEdge(0, "C", 2);
            secondDfa.AddEdge(2, "A", 3);
            secondDfa.AddEdge(1, "E", 4);

            var thirdDfa = new Dfa <string>();

            var rules = new Dictionary <string, IDfa <Optional <Rule <string> >, string> >
            {
                ["A"] = firstDfa,
                ["B"] = secondDfa,
                ["C"] = thirdDfa
            };

            var grammar = new CompiledGrammar <string> {
                Rules = rules
            };

            var nullables = new List <DfaAndState <string> >
            {
                new DfaAndState <string> {
                    Dfa = thirdDfa, State = new ValueState <int>(0)
                }
            };

            var firstSymbols = FirstHelper <string> .GetFirstSymbols(grammar, nullables);

            var expected = new[]
            {
                new[] { "A,B,C,D,F", string.Empty, "A,B,C,D,F", "A,B,C,D,F", "G", string.Empty, "A,B,C,D,F", string.Empty },
                new[] { "A,B,C,D,F", "E", "A,B,C,D,F", string.Empty, string.Empty },
                new[] { string.Empty }
            };
            var size = new int[] { 8, 5, 1 };
            var dfas = new ConcreteDfa <Optional <Rule <string> >, string>[] { firstDfa, secondDfa, thirdDfa };

            for (int test = 0; test < 3; ++test)
            {
                for (int i = 0; i < size[test]; ++i)
                {
                    var stateEntity = new DfaAndState <string> {
                        Dfa = dfas[test], State = new ValueState <int>(i)
                    };
                    string output = string.Join(',', firstSymbols[stateEntity].OrderBy(x => x));
                    Assert.AreEqual(expected[test][i], output, $"Unexpected output on test ({test}, {i}): expected is [{expected[test][i]}], but found [{output}]");
                }
            }
        }
示例#3
0
        public void Test1()
        {
            // Z –> d | XYZ
            // Y –> c | a
            // X –> Y | ε

            var rules = new Dictionary <char, IDfa <Optional <Rule <char> >, char> >();

            var zdfa = new ConcreteDfa <Optional <Rule <char> >, char>();

            zdfa.Magic = 0;
            zdfa.AddEdge(0, 'X', 1);
            zdfa.AddEdge(1, 'Y', 2);
            zdfa.AddEdge(2, 'Z', 3);
            zdfa.AddEdge(0, 'd', 3);
            zdfa.Labels.Add(0, REJECT);
            zdfa.Labels.Add(1, REJECT);
            zdfa.Labels.Add(2, REJECT);
            zdfa.Labels.Add(3, this.ACCEPT('Z'));
            rules.Add('Z', zdfa);

            var ydfa = new ConcreteDfa <Optional <Rule <char> >, char>();

            ydfa.Magic = 1;
            ydfa.AddEdge(0, 'c', 1);
            ydfa.AddEdge(0, 'a', 1);
            ydfa.Labels.Add(0, REJECT);
            ydfa.Labels.Add(1, this.ACCEPT('Y'));
            rules.Add('Y', ydfa);

            var xdfa = new ConcreteDfa <Optional <Rule <char> >, char>();

            xdfa.Magic = 2;
            xdfa.AddEdge(0, 'Y', 1);
            xdfa.Labels.Add(0, this.ACCEPT('X'));
            xdfa.Labels.Add(1, this.ACCEPT('X'));
            rules.Add('X', xdfa);

            var grammar = new CompiledGrammar <char> {
                Rules = rules, StartSymbol = 'Z'
            };
            var nullables = NullablesHelper <char> .GetNullableSymbols(grammar);

            {
                var output = nullables.OrderBy(x => (x.Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic).ThenBy(x => (x.State as ValueState <int>).Value).ToList();
                Assert.AreEqual(4, output.Count);
                Assert.AreEqual(0, (output[0].Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic);
                Assert.AreEqual(3, (output[0].State as ValueState <int>).Value);
                Assert.AreEqual(1, (output[1].Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic);
                Assert.AreEqual(1, (output[1].State as ValueState <int>).Value);
                Assert.AreEqual(2, (output[2].Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic);
                Assert.AreEqual(0, (output[2].State as ValueState <int>).Value);
                Assert.AreEqual(2, (output[3].Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic);
                Assert.AreEqual(1, (output[3].State as ValueState <int>).Value);
            }

            var first = FirstHelper <char> .GetFirstSymbols(grammar, nullables);

            {
                var output = first.OrderBy(x => (x.Key.Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic).ThenBy(x => (x.Key.State as ValueState <int>).Value).ToList();

                var symbols = output[0].Value.ToList(); // Z0
                symbols.Sort();
                Assert.AreEqual(5, symbols.Count);
                Assert.AreEqual('X', symbols[0]);
                Assert.AreEqual('Y', symbols[1]);
                Assert.AreEqual('a', symbols[2]);
                Assert.AreEqual('c', symbols[3]);
                Assert.AreEqual('d', symbols[4]);

                symbols = output[1].Value.ToList(); // Z1
                symbols.Sort();
                Assert.AreEqual(3, symbols.Count);
                Assert.AreEqual('Y', symbols[0]);
                Assert.AreEqual('a', symbols[1]);
                Assert.AreEqual('c', symbols[2]);

                symbols = output[2].Value.ToList(); // Z2
                symbols.Sort();
                Assert.AreEqual(6, symbols.Count);
                Assert.AreEqual('X', symbols[0]);
                Assert.AreEqual('Y', symbols[1]);
                Assert.AreEqual('Z', symbols[2]);
                Assert.AreEqual('a', symbols[3]);
                Assert.AreEqual('c', symbols[4]);
                Assert.AreEqual('d', symbols[5]);

                symbols = output[3].Value.ToList(); // Z3
                Assert.AreEqual(0, symbols.Count);

                symbols = output[4].Value.ToList(); // Y0
                symbols.Sort();
                Assert.AreEqual(2, symbols.Count);
                Assert.AreEqual('a', symbols[0]);
                Assert.AreEqual('c', symbols[1]);

                symbols = output[5].Value.ToList(); // Y1
                Assert.AreEqual(0, symbols.Count);

                symbols = output[6].Value.ToList(); // X0
                symbols.Sort();
                Assert.AreEqual(3, symbols.Count);
                Assert.AreEqual('Y', symbols[0]);
                Assert.AreEqual('a', symbols[1]);
                Assert.AreEqual('c', symbols[2]);

                symbols = output[7].Value.ToList(); // X1
                Assert.AreEqual(0, symbols.Count);
            }

            var follow = FollowHelper <char> .GetFollowSymbols(grammar, nullables, first.InverseRelation(), '\uffff');

            {
                var output = follow.OrderBy(x => (x.Key.Dfa as ConcreteDfa <Optional <Rule <char> >, char>).Magic).ThenBy(x => (x.Key.State as ValueState <int>).Value).ToList();

                var symbols = output[0].Value.ToList(); // Z3
                Assert.AreEqual(1, symbols.Count);
                Assert.AreEqual('\uffff', symbols[0]);

                symbols = output[1].Value.ToList(); // Y1
                symbols.Sort();
                Assert.AreEqual(6, symbols.Count);
                Assert.AreEqual('X', symbols[0]);
                Assert.AreEqual('Y', symbols[1]);
                Assert.AreEqual('Z', symbols[2]);
                Assert.AreEqual('a', symbols[3]);
                Assert.AreEqual('c', symbols[4]);
                Assert.AreEqual('d', symbols[5]);

                symbols = output[2].Value.ToList(); // X0
                symbols.Sort();
                Assert.AreEqual(3, symbols.Count);
                Assert.AreEqual('Y', symbols[0]);
                Assert.AreEqual('a', symbols[1]);
                Assert.AreEqual('c', symbols[2]);

                symbols = output[3].Value.ToList(); // X1
                symbols.Sort();
                Assert.AreEqual(3, symbols.Count);
                Assert.AreEqual('Y', symbols[0]);
                Assert.AreEqual('a', symbols[1]);
                Assert.AreEqual('c', symbols[2]);
            }
        }
示例#4
0
        public void Test0SimpleParens()
        {
            var rules = new Dictionary <char, IDfa <Optional <Rule <char> >, char> >();

            var dfa = new ConcreteDfa <Optional <Rule <char> >, char>();

            dfa.AddEdge(0, '(', 1);
            dfa.AddEdge(1, 'S', 2);
            dfa.AddEdge(2, ')', 3);
            dfa.Labels.Add(0, this.ACCEPT('S'));
            dfa.Labels.Add(1, REJECT);
            dfa.Labels.Add(2, REJECT);
            dfa.Labels.Add(3, this.ACCEPT('S'));
            rules.Add('S', dfa);
            var grammar = new CompiledGrammar <char> {
                Rules = rules, StartSymbol = 'S'
            };
            var nullables = NullablesHelper <char> .GetNullableSymbols(grammar);

            {
                Assert.AreEqual(2, nullables.Count);
                var states = nullables.Select(x => ((ValueState <int>)x.State).Value).ToList();
                states.Sort();
                Assert.AreEqual(0, states[0]);
                Assert.AreEqual(3, states[1]);
            }

            var first = FirstHelper <char> .GetFirstSymbols(grammar, nullables);

            {
                var output = first.OrderBy(x => (x.Key.State as ValueState <int>).Value).ToList();

                var symbols = output[0].Value.ToList();
                Assert.AreEqual(1, symbols.Count);
                Assert.AreEqual('(', symbols[0]);

                symbols = output[1].Value.ToList();
                symbols.Sort();
                Assert.AreEqual(3, symbols.Count);
                Assert.AreEqual('(', symbols[0]);
                Assert.AreEqual(')', symbols[1]);
                Assert.AreEqual('S', symbols[2]);

                symbols = output[2].Value.ToList();
                Assert.AreEqual(1, symbols.Count);
                Assert.AreEqual(')', symbols[0]);

                symbols = output[3].Value.ToList();
                Assert.AreEqual(0, symbols.Count);
            }

            var follow = FollowHelper <char> .GetFollowSymbols(grammar, nullables, first.InverseRelation(), '\uffff');

            {
                var output = follow.OrderBy(x => (x.Key.State as ValueState <int>).Value).ToList();

                var symbols = output[0].Value.ToList(); // state 0
                symbols.Sort();
                Assert.AreEqual(2, symbols.Count);
                Assert.AreEqual(')', symbols[0]);
                Assert.AreEqual('\uffff', symbols[1]);

                symbols = output[1].Value.ToList(); // state 3
                symbols.Sort();
                Assert.AreEqual(2, symbols.Count);
                Assert.AreEqual(')', symbols[0]);
                Assert.AreEqual('\uffff', symbols[1]);
            }
        }