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("}"); } }
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));