Beispiel #1
0
        /// <summary>
        /// Creates and returns the LR(0) canonical sets for the given <paramref name="grammar"/>.
        /// </summary>
        /// <param name="grammar">The grammar to build the canonical sets for.</param>
        /// <returns>The built canonical sets.</returns>
        /// <exception cref="ArgumentNullException"> if <paramref name="grammar"/> is <c>null</c>.</exception>
        public static LR0CanonicalSets Build( RestrictedStartSymbolGrammar grammar )
        {
            if( grammar == null )
                throw new ArgumentNullException("grammar");

            var terms_and_gramms = new List<Symbol>();
            terms_and_gramms.AddRange(grammar.Grammaticals);
            terms_and_gramms.AddRange(grammar.Terminals);
            var sets = new LR0CanonicalSets();

            // Calculate the I0 canonical set from the 'starting' rule
            var s0 = new HashSet<LR0Item>();
            if( grammar.Rules.Count > 0 )
                s0.Add(new LR0Item(grammar.StartRule, 0));
            var I0 = Closure(s0, grammar);
            sets.Add(I0);

            // Generate LR0CanonicalSets with Read()
            for( int current_set_id = 0; current_set_id < sets.Sets.Count; ++current_set_id )
                // Generate new sets for every symbol read
                foreach( var symbol in terms_and_gramms )
                {
                    var new_I = Read(sets.Sets[current_set_id], symbol, grammar);

                    // If the set is empty then continue
                    if( new_I.Count == 0 )
                        continue;

                    // Identify new_I
                    int next_set_id = sets.IndexOf(new_I);

                    // If this is a new CanonicalSet then add to the group
                    if( next_set_id == -1 )
                        next_set_id = sets.Add(new_I);

                    // Record the state transition
                    sets.SetTransition(current_set_id, symbol, next_set_id);
                }

            return sets;
        }