Пример #1
0
        /// <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;
        }
Пример #2
0
        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;
        }
Пример #3
0
        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;
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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;
        }
Пример #6
0
        /// <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;
        }
Пример #7
0
        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;
        }
Пример #8
0
 public static void ReflexiveClosure( RelationMatrix relation )
 {
     // Set the diagonal to 'true's.
     for( int i = 0; i < relation.Dimension; ++i )
         relation[i, i] = true;
 }
Пример #9
0
 /// <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);
 }
Пример #10
0
        /// <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];
        }
Пример #11
0
 /// <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;
 }