/// <summary> /// Calculates the first sets of all grammaticals of the given <paramref name="grammar"/>. /// </summary> /// <param name="grammar">The grammaticals which are to examen, are in this grammar.</param> /// <param name="epsilon_grammaticals">Set of the epsilon capable grammaticals of the given /// <paramref name="grammar"/>. (see <see cref="EpsilonGrammaticals"/>)</param> /// <returns>The first sets for all the grammaticals of the given <paramref name="grammar"/>.</returns> /// <exception cref="ArgumentNullException"> if any of the parameters is <c>null</c>.</exception> public static IDictionary<GrammaticalSymbol, ISet<TerminalSymbol>> Build( ExtendedGrammar grammar, ISet<GrammaticalSymbol> epsilon_grammaticals) { if( grammar == null ) throw new ArgumentNullException("grammar"); if( epsilon_grammaticals == null ) throw new ArgumentNullException("epsilon_grammaticals"); // Relation matrix var f_plus = new RelationMatrix(grammar.Terminals.Count + grammar.Grammaticals.Count); RelationMatrix.TransitiveClosure(F_Relation(grammar), f_plus); // Build the first_sets var first_sets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); foreach( var gr in grammar.Grammaticals ) { int gr_index = grammar.GlobalIndexOf(gr); // Put all terminals being in relation with gr into gr's first_set var first_set = new HashSet<TerminalSymbol>(); foreach( var tr in grammar.Terminals ) if( f_plus[gr_index, grammar.GlobalIndexOf(tr)] ) first_set.Add(tr); if( epsilon_grammaticals.Contains(gr) ) first_set.Add(EpsilonSymbol.Instance); first_sets.Add(gr, first_set); } return first_sets; }
/// <summary> /// Calculates the follow sets of all grammaticals of the given <paramref name="grammar"/>. /// </summary> /// <param name="grammar">The grammaticals which are to examen, are in this grammar.</param> /// <param name="epsilon_grammaticals">Set of the epsilon capable grammaticals of the given /// <paramref name="grammar"/>. (see <see cref="EpsilonGrammaticals"/>)</param> /// <returns>The first sets for all the grammaticals of the given <paramref name="grammar"/>.</returns> /// <exception cref="ArgumentNullException"> if any of the parameters is <c>null</c>.</exception> public static IDictionary<GrammaticalSymbol, ISet<TerminalSymbol>> Build( ExtendedGrammar grammar, ISet<GrammaticalSymbol> epsilon_grammaticals) { if( grammar == null ) throw new ArgumentNullException("grammar"); if( epsilon_grammaticals == null ) throw new ArgumentNullException("epsilon_grammaticals"); int symbol_count = grammar.Terminals.Count + grammar.Grammaticals.Count; var f_star = new RelationMatrix(symbol_count); RelationMatrix.TransitiveClosure(FirstSets.F_Relation(grammar), f_star); RelationMatrix.ReflexiveClosure(f_star); var l_star = new RelationMatrix(symbol_count); RelationMatrix.TransitiveClosure(L_Relations(grammar, epsilon_grammaticals), l_star); RelationMatrix.ReflexiveClosure(l_star); var b = B_Relation(grammar, epsilon_grammaticals); var tmp = new RelationMatrix(symbol_count); var lbf = new RelationMatrix(symbol_count); RelationMatrix.WharshallAlg(l_star, b, tmp); RelationMatrix.WharshallAlg(tmp, f_star, lbf); // Build the follow_sets var follow_sets = new Dictionary<GrammaticalSymbol, ISet<TerminalSymbol>>(); foreach( var gr in grammar.Grammaticals ) { int gr_index = grammar.GlobalIndexOf(gr); // Put all terminals being in relation with gr into gr's follow_set var follow_set = new HashSet<TerminalSymbol>(); foreach( var tr in grammar.Terminals ) if( lbf[gr_index, grammar.GlobalIndexOf(tr)] ) follow_set.Add(tr); follow_sets.Add(gr, follow_set); } return follow_sets; }