Пример #1
0
        public void SimpleParenTest()
        {
            var grammar   = new Grammar <ParenAlphabet>();
            var ruleParen =
                new Rule <ParenAlphabet>
            {
                Name = "paren",
                Lhs  = ParenAlphabet.Expr,
                Rhs  = Concat <ParenAlphabet>(
                    ParenAlphabet.L.ToRegex(),
                    ParenAlphabet.Expr.ToRegex(),
                    ParenAlphabet.R.ToRegex())
            };
            var ruleX =
                new Rule <ParenAlphabet> {
                Name = "X", Lhs = ParenAlphabet.Expr, Rhs = ParenAlphabet.X.ToRegex()
            };

            grammar.Rules = new List <Rule <ParenAlphabet> >()
            {
                ruleParen,
                ruleX
            };
            grammar.StartSymbol = ParenAlphabet.Expr;

            var compiledGrammar = GrammarCompiler <ParenAlphabet> .CompileGrammar(grammar);

            var follow = FollowHelper <ParenAlphabet> .GetFollowSymbols(compiledGrammar, null, null, ParenAlphabet.EOF);

            foreach (var c in follow)
            {
                Console.WriteLine("state: " + c.Key.Dfa.Label(c.Key.State) + " follow: " + string.Join(",", c.Value));
            }
        }
Пример #2
0
        public void HarderParenTest()
        {
            var grammar = new Grammar <ParenAlphabet>
            {
                Rules = new List <Rule <ParenAlphabet> >()
                {
                    new Rule <ParenAlphabet>
                    {
                        Name = "paren",
                        Lhs  = ParenAlphabet.Expr,
                        Rhs  = Concat(
                            ParenAlphabet.L.ToRegex(),
                            ParenAlphabet.Expr.ToRegex(),
                            ParenAlphabet.S.ToRegex(),
                            ParenAlphabet.R.ToRegex())
                    },
                    new Rule <ParenAlphabet> {
                        Name = "X", Lhs = ParenAlphabet.Expr, Rhs = ParenAlphabet.X.ToRegex()
                    },
                    new Rule <ParenAlphabet>
                    {
                        Name = "SY", Lhs = ParenAlphabet.S, Rhs = ParenAlphabet.Y.ToRegex().Optional()
                    },
                },
                StartSymbol = ParenAlphabet.Expr
            };

            var compiledGrammar = GrammarCompiler <ParenAlphabet> .CompileGrammar(grammar);

            var follow = FollowHelper <ParenAlphabet> .GetFollowSymbols(compiledGrammar, null, null, ParenAlphabet.EOF);

            foreach (var c in follow)
            {
                Console.WriteLine("state: " + c.Key.Dfa.Label(c.Key.State) + " follow: " + string.Join(",", c.Value));
            }
        }
Пример #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]);
            }
        }