/// <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; }
private static RelationMatrix B_Relation( IGrammar grammar, ISet<GrammaticalSymbol> epsilon_grammaticals ) { var relation = new RelationMatrix(grammar.Terminals.Count + grammar.Grammaticals.Count); foreach( var rule in grammar.Rules ) for( int i = 1; i < rule.RightHandSide.Count; ++i ) { relation[ grammar.GlobalIndexOf(rule.RightHandSide[i - 1]), grammar.GlobalIndexOf(rule.RightHandSide[i])] = true; for( int j = i + 1; j < rule.RightHandSide.Count; ++j ) if( rule.RightHandSide[j - 1] is GrammaticalSymbol && epsilon_grammaticals.Contains((GrammaticalSymbol)rule.RightHandSide[j - 1]) ) { relation[ grammar.GlobalIndexOf(rule.RightHandSide[i - 1]), grammar.GlobalIndexOf(rule.RightHandSide[j])] = true; } else { break; } } return relation; }
internal static RelationMatrix F_Relation( IGrammar grammar ) { var relation = new RelationMatrix(grammar.Terminals.Count + grammar.Grammaticals.Count); foreach( var rule in grammar.Rules ) if( rule.RightHandSide.Count > 0 ) relation[ grammar.GlobalIndexOf(rule.LeftHandSide), grammar.GlobalIndexOf(rule.RightHandSide[0])] = true; return relation; }
public static void TransitiveClosure( RelationMatrix relation, RelationMatrix result ) { var temp = relation.Copy(); relation.CopyTo(result); for( int i = 0; i < relation.Dimension - 1; ++i ) { WharshallAlg(temp, relation, result); result.CopyTo(temp); } }
public static void WharshallAlg( RelationMatrix left, RelationMatrix right, RelationMatrix result ) { if( left == null ) throw new ArgumentNullException("left"); if( right == null ) throw new ArgumentNullException("right"); if( result == null ) throw new ArgumentNullException("result"); if( left.Dimension != right.Dimension || left.Dimension != result.Dimension ) throw new ArgumentException("Dimension mismatch."); for( int j = 0; j < left.Dimension; ++j ) for( int i = 0; i < left.Dimension; ++i ) if( left[i, j] ) for( int k = 0; k < left.Dimension; ++k ) if( right[j, k] ) result[i, k] = true; }
/// <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; }
private static RelationMatrix L_Relations( IGrammar grammar, ISet<GrammaticalSymbol> epsilon_grammaticals ) { var relation = new RelationMatrix(grammar.Terminals.Count + grammar.Grammaticals.Count); foreach( var rule in grammar.Rules ) if( rule.RightHandSide.Count > 0 ) { relation[ grammar.GlobalIndexOf(rule.RightHandSide[rule.RightHandSide.Count - 1]), grammar.GlobalIndexOf(rule.LeftHandSide)] = true; for( int i = rule.RightHandSide.Count - 2; i >= 0; --i ) if( rule.RightHandSide[i + 1] is GrammaticalSymbol && epsilon_grammaticals.Contains((GrammaticalSymbol)rule.RightHandSide[i + 1]) ) { relation[ grammar.GlobalIndexOf(rule.RightHandSide[i]), grammar.GlobalIndexOf(rule.LeftHandSide)] = true; } else { break; } } return relation; }
public static void ReflexiveClosure( RelationMatrix relation ) { // Set the diagonal to 'true's. for( int i = 0; i < relation.Dimension; ++i ) relation[i, i] = true; }
/// <summary> /// Tells if this matrix is considered equal to the given one. /// </summary> /// <param name="other">The other matrix to compare with.</param> /// <returns><c>true</c> if the given matrix is equal to this, <c>false</c> otherwise.</returns> public bool Equals( RelationMatrix other ) { return other != null && this.dim == other.dim && Array.Equals(this.relations, other.relations); }
/// <summary> /// Copies the content of this matrix into the given <paramref name="other"/> one. /// The dimensions of the matrices must be the same. /// </summary> /// <param name="other">The matrix to copy into.</param> /// <exception cref="ArgumentNullException"> if <paramref name="other"/> is <c>null</c>.</exception> /// <exception cref="ArguemtnException"> if <paramref name="other"/> has not the same dimension as this matrix.</exception> public void CopyTo( RelationMatrix other ) { if( other == null ) throw new ArgumentNullException("other"); if( this.dim != other.dim ) throw new ArgumentException("Dimension mismatch."); for( int i = 0; i < this.dim; ++i ) for( int j = 0; j < this.dim; ++j ) other.relations[i, j] = this.relations[i, j]; }
/// <summary> /// Creates and returns a new matrix instance with the contents of this matrix. /// </summary> /// <returns>A new instance, a copy of this.</returns> public RelationMatrix Copy() { var copy = new RelationMatrix(this.dim); this.CopyTo(copy); return copy; }