// // Context-Free languages, CFG and LR Parsing // /// <summary> /// G3 in "A Survey of LR-Parsing Methods", Gallier. /// </summary> public static void GallierLookaheadLR_Example3() { var grammar = DragonBookExample4_48.GetGrammar(); // characteristic automaton (LR(0) automaton) var dfaLr0 = grammar.GetLr0AutomatonDfa(); SaveFile("GallierEx3_LR0Automaton.dot", DotLanguagePrinter.ToDotLanguage(dfaLr0, DotRankDirection.LeftRight, skipStateLabeling: true)); var analyzer = Analyzers.CreateErasableSymbolsAnalyzer(grammar); //(ImmutableArray<IReadOnlySet<Terminal>> initfirstSets, IGraph graphFirst) = DigraphAlgorithm.GetFirstGraph(grammar, analyzer); (var initfirstSets, IGraph graphFirst) = DigraphAlgorithm.GetFirstGraph(grammar, analyzer); SaveFile("GallierEx3_FirstGraph.dot", DigraphDotLanguagePrinter.PrintGraph("INITFIRST", initfirstSets, graphFirst, v => grammar.Nonterminals[v].Name)); var firstSymbolsAnalyzer = Analyzers.CreateFirstSymbolsAnalyzer(grammar); (var initFollowSets, IGraph graphFollow) = DigraphAlgorithm.GetFollowGraph(grammar, firstSymbolsAnalyzer); SaveFile("GallierEx3_FollowGraph.dot", DigraphDotLanguagePrinter.PrintGraph("INITFOLLOW", initFollowSets, graphFollow, v => grammar.Nonterminals[v].Name)); var stringWriter = new StringWriter(); grammar.PrintFirstAndFollowSets(stringWriter); SaveFile("GallierEx3_FirstAndFollowSets.txt", stringWriter.ToString()); // Grammar is LR(0) var lr0Parser = grammar.ComputeLr0ParsingTable(); var writer = new StringWriter(); lr0Parser.PrintParsingTable(writer); foreach (var conflict in lr0Parser.Conflicts) { writer.WriteLine(conflict); writer.WriteLine($"In state {conflict.State}: {lr0Parser.GetItems(conflict.State).KernelItems.ToVectorString()} (kernel items)"); } writer.WriteLine(); SaveFile("GallierEx3_Lr0ParsingTable.txt", writer.ToString()); //// var vertices = LalrLookaheadSetsAlgorithm.GetGotoTransitionPairs(grammar, dfaLr0); // Read (INITFOLLOW) sets var(directReads, graphRead) = LalrLookaheadSetsAlgorithm.GetGraphReads(grammar, dfaLr0, vertices, analyzer); SaveFile("GallierEx3_ReadGraph.dot", DigraphDotLanguagePrinter.PrintGraph("DR", directReads, graphRead, v => vertices[v].ToString())); var graphLaFollow = LalrLookaheadSetsAlgorithm.GetGraphLaFollow(grammar, dfaLr0, vertices, analyzer); SaveFile("GallierEx3_LaFollowGraph.dot", DigraphDotLanguagePrinter.PrintGraph("INITFOLLOW", directReads, graphLaFollow, v => vertices[v].ToString())); }
public static void DigraphMethods() { var grammar = GallierCalc.GetGrammar(); var analyzer = Analyzers.CreateErasableSymbolsAnalyzer(grammar); (var initfirstSets, IGraph graphFirst) = DigraphAlgorithm.GetFirstGraph(grammar, analyzer); SaveFile("FirstGraph.dot", DigraphDotLanguagePrinter.PrintGraph("INITFIRST", initfirstSets, graphFirst, v => grammar.Nonterminals[v].Name)); var firstSymbolsAnalyzer = Analyzers.CreateFirstSymbolsAnalyzer(grammar); (var initFollowSets, IGraph graphFollow) = DigraphAlgorithm.GetFollowGraph(grammar, firstSymbolsAnalyzer); SaveFile("FollowGraph.dot", DigraphDotLanguagePrinter.PrintGraph("INITFOLLOW", initFollowSets, graphFollow, v => grammar.Nonterminals[v].Name)); }
public void GetFollowGraph() { var analyzer = Analyzers.CreateFirstSymbolsAnalyzer(Grammar); var(initSets, graph) = DigraphAlgorithm.GetFollowGraph(Grammar, analyzer); // INITFOLLOW(S) initSets[0].ShouldBeEmpty(); // INITFOLLOW(E) initSets[1].ShouldSetEqual(Grammar.Ts(Sym.PLUS, Sym.RPARAN, Sym.EOF)); // INITFOLLOW(T) initSets[2].ShouldSetEqual(Grammar.Ts(Sym.ASTERISK)); // INITFOLLOW(F) initSets[3].ShouldBeEmpty(); var closureSets = DigraphAlgorithm.Traverse(graph, new[] { // trick to inspect closure (unions) new Set <string> { "S" }, new Set <string> { "E" }, new Set <string> { "T" }, new Set <string> { "F" } }); // FOLLOW(S) = INITFOLLOW(S) closureSets[0].ShouldSetEqual("S"); // FOLLOW(E) = INITFOLLOW(S) ∪ INITFOLLOW(E) closureSets[1].ShouldSetEqual("S", "E"); // FOLLOW(T) = INITFOLLOW(S) ∪ INITFOLLOW(E) ∪ INITFOLLOW(T) ∪ INITFOLLOW(F) closureSets[2].ShouldSetEqual("S", "E", "T", "F"); // FOLLOW(F) = INITFOLLOW(S) ∪ INITFOLLOW(E) ∪ INITFOLLOW(T) ∪ INITFOLLOW(F) closureSets[3].ShouldSetEqual("S", "E", "T", "F"); }