Пример #1
0
        public static void Main()
        {
            Grammar grammar;

            while (true)
            {
                try
                {
                    grammar = GrammarReader.ReadGrammar();
                    break;
                }
                catch
                {
                    Console.WriteLine("Неверный формат ввода");
                }
            }

            Console.WriteLine("Грамматика G:");
            Console.Write("\nVn: { ");
            for (var i = 0; i < grammar.VN.Count - 1; ++i)
            {
                Console.Write($"{grammar.VN[i]}, ");
            }
            Console.Write($"{grammar.VN.Last()} }}");
            Console.Write("\nVt: { ");
            for (var i = 0; i < grammar.VT.Count - 1; ++i)
            {
                Console.Write($"{grammar.VT[i]}, ");
            }
            Console.Write($"{grammar.VT.Last()} }}");
            Console.WriteLine("\nПравила: ");
            foreach (var rule in grammar.Rules)
            {
                Console.WriteLine($"{rule.LeftSide} -> {rule.RightSide}");
            }

            var solver = new FirstFollowFinder(grammar);

            int k;

            while (true)
            {
                Console.Write("Введите k: ");
                var res = int.TryParse(Console.ReadLine(), out k);
                if (res && k > 0)
                {
                    break;
                }
            }

            Console.WriteLine("\nFIRSTk для нетерминалов:");
            var firsts = solver.FirstForNonterminal(k);

            foreach (var nt in firsts.Keys)
            {
                Console.Write($"FIRST({nt}): {{ ");
                foreach (var e in firsts[nt])
                {
                    if (e == "ε")
                    {
                        Console.Write("epsilon");
                    }
                    else
                    {
                        Console.Write($"{e}");
                    }


                    if (firsts[nt].IndexOf(e) != firsts[nt].Count - 1)
                    {
                        Console.Write($",");
                    }

                    Console.Write(" ");
                }
                Console.WriteLine("}");
            }

            Console.WriteLine("\nFOLLOWk для нетерминалов:");
            var follows = solver.FollowForNonterminal(k);

            foreach (var nt in follows.Keys)
            {
                Console.Write($"FOLLOW({nt}): {{ ");
                foreach (var e in follows[nt])
                {
                    if (e == "ε")
                    {
                        Console.Write("epsilon");
                    }
                    else
                    {
                        Console.Write($"{e}");
                    }

                    if (follows[nt].IndexOf(e) != follows[nt].Count - 1)
                    {
                        Console.Write($",");
                    }

                    Console.Write(" ");
                }
                Console.WriteLine("}");
            }
        }
Пример #2
0
        private static Dictionary <(char, char), List <List <string> > > SigmaI(Grammar g, FirstFollowFinder firstFollowFinder, int k)
        {
            // Строим sigma_0
            var sigma_0 = new Dictionary <(char, char), List <List <string> > >();

            foreach (var ntA in g.VN)
            {
                foreach (var ntB in g.VN)
                {
                    sigma_0.Add((ntA, ntB), new List <List <string> >());

                    foreach (var rule in g.Rules)
                    {
                        if (rule.LeftSide == ntA.ToString())
                        {
                            if (rule.RightSide.Contains(ntB))
                            {
                                for (var i = 0; i < rule.RightSide.Length; ++i)
                                {
                                    if (rule.RightSide[i] == ntB)
                                    {
                                        var alpha = rule.RightSide.Substring(i + 1, rule.RightSide.Length - i - 1);
                                        sigma_0[(ntA, ntB)].Add(firstFollowFinder.First(k, alpha));