Пример #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
        /// <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;
        }