Пример #1
0
        private Hashtable SplitGroup(ail.net.parser.FsaStateSet xi_group, Hashtable xi_partition)
        {
            ail.net.framework.Assert.NonNullReference(xi_group, "xi_group");
            ail.net.framework.Assert.Condition(xi_group.States.Count > 0, "xi_group.States.Count > 0");
            ail.net.framework.Assert.NonNullReference(xi_partition, "xi_partition");

            Hashtable result = new Hashtable();

            // first state introduces new subgroup
            ail.net.parser.FsaStateSet group = new ail.net.parser.FsaStateSet(GroupCounter.Next());

            result.Add(group.Id, group);

            group.States.Add(((ail.net.parser.FsaState)ail.net.framework.Functor.FirstElementOfCollection(xi_group.States.Values)).Id,
                             (ail.net.parser.FsaState)ail.net.framework.Functor.FirstElementOfCollection(xi_group.States.Values));

            // go over states in the group
            foreach (ail.net.parser.FsaState state in xi_group.States.Values)
            {
                bool added = false;

                // check if state is not ortogonal to any subgroup
                foreach (ail.net.parser.FsaStateSet subgroup in result.Values)
                {
                    if (subgroup.States.Contains(state.Id)) // state == state
                    {
                        added = true;
                        break;
                    }

                    ail.net.parser.FsaState group_state = (ail.net.parser.FsaState)ail.net.framework.Functor.FirstElementOfCollection(subgroup.States.Values);

                    if (AreEqual(state, group_state, xi_partition))
                    {
                        subgroup.States.Add(state.Id, state);
                        added = true;
                        break;
                    }
                }

                // if state is ortogonal introduce a new group and add state to this new group
                if (!added)
                {
                    group = new ail.net.parser.FsaStateSet(GroupCounter.Next());
                    result.Add(group.Id, group);
                    group.States.Add(state.Id, state);
                }
            }

            return(result);
        }
Пример #2
0
        private void BuildTable(ref Hashtable xio_partition)
        {
            //!! not implemented due to huge tables being built, postponed :(
            // Mark the distinguishable pairs of states.
            // To achieve this task, we first mark all pairs (p,q), where p belongs to F and
            // q does not belong to F as distinguishable. Then, we proceed as follows:
            //      repeat
            //          for all non-marked pairs {p,q} do
            //              for each letter 'a' do
            //                  if the pair {(s)igma(p,a), (s)igma(q,a)} is marked
            //                      then mark {p,q}
            //      until no new pairs are marked
            ail.net.framework.Assert.NonNullReference(xio_partition, "xio_partition");

            // initialization, this algorithm is sensitive to states organization
            ResetMarkedStates();

            xio_partition.Clear();

            // table for 'A B C D E' states, cells in use marked with '*'
            //     0 A
            //     1 B *
            //     2 C * *
            //     3 D * * *
            //     4 E * * * *
            //         A B C D E
            //         0 1 2 3 4
            // access by (p, q) = table[ArithmeticProgressionSum(Math.Max(0, p_id-1)+q_id]

            // map[index][state]
            ArrayList map = new ArrayList(States.Values);

            Hashtable table = new Hashtable(CalculateTableSize());

            // create table of pairs, also mark all pairs of accept and non-accept states as non-equivalent
            // keep only one of pairs (p, q) or (q, p)
            ArrayList states = new ArrayList(States.Values);

            states.Sort(); // states must be numbered in sequence

            for (int i = 0; i < states.Count - 1; i++)
            {
                for (int j = i + 1; j < states.Count; j++)
                {
                    ail.net.parser.FsaState p_state = (ail.net.parser.FsaState)states[i];
                    ail.net.parser.FsaState q_state = (ail.net.parser.FsaState)states[j];

                    ail.net.parser.FsaPair pair = new ail.net.parser.FsaPair(p_state, q_state);

                    table.Add(new ail.net.parser.FsaPairKey(p_state, q_state), pair);

                    bool p_final = IsFinalState(p_state);
                    bool q_final = IsFinalState(q_state);

                    bool mark = ((p_final && !q_final) || (!p_final && q_final));

                    if (!mark && p_final && q_final)
                    {
                        mark = p_state.Token.Type != q_state.Token.Type;
                    }

                    if (mark)
                    {
                        pair.Marked = true;
                    }
                }
            }

            // populate table
            for (;;)
            {
                bool process = false;

                foreach (ail.net.parser.FsaPair pair in table.Values)
                {
                    if (!pair.Marked)
                    {
                        Hashtable predicates = CombinePredicates(pair.PState, pair.QState);

                        foreach (ail.net.parser.FsaTransitionPredicate predicate in predicates.Values)
                        {
                            ail.net.parser.FsaTransition p_state_t = pair.PState.GetTransitionByPredicate(predicate);
                            ail.net.parser.FsaTransition q_state_t = pair.QState.GetTransitionByPredicate(predicate);

                            if ((p_state_t == (object)null || q_state_t == (object)null))
                            {
                                continue;
                            }

                            ail.net.parser.FsaState p_state = (ail.net.parser.FsaState)States[p_state_t.End];
                            ail.net.parser.FsaState q_state = (ail.net.parser.FsaState)States[q_state_t.End];

                            if ((object)p_state == (object)q_state) // pairs with same states are assumped unmarked
                            {
                                continue;
                            }

                            ail.net.parser.FsaPair sigma_pair = GetPairFromStates(p_state, q_state, table);

                            if (sigma_pair.Marked)
                            {
                                pair.Marked = true;
                                process     = true;
                            }
                        }
                    }
                }

                if (!process)
                {
                    break;
                }
            }

            ResetMarkedStates();

            // build partition
            foreach (ail.net.parser.FsaState state in states)
            {
                if (!state.Marked)
                {
                    // add equivalent groups, optimistic assumption
                    ail.net.parser.FsaStateSet group = new ail.net.parser.FsaStateSet(0);

                    for (int i = 0; i < state.Id; i++)
                    {
                        ail.net.parser.FsaPair pair = GetPairFromStates((ail.net.parser.FsaState)States[i], state, table);

                        if (!pair.Marked)
                        {
                            if ((object)pair.QState != (object)state)
                            {
                                if (!pair.QState.Marked)
                                {
                                    group.States.Add(pair.QState.Id, pair.QState);
                                }
                            }
                            else
                            {
                                if (!pair.PState.Marked)
                                {
                                    group.States.Add(pair.PState.Id, pair.PState);
                                }
                            }
                        }
                    }

                    if (group.States.Count > 0)
                    {
                        group.States.Add(state.Id, state);
                        group.Id = GroupCounter.Next(); // correct id

                        xio_partition.Add(group.Id, group);

                        foreach (ail.net.parser.FsaState group_state in group.States.Values)
                        {
                            group_state.Marked = true;
                        }
                    }
                }
            }

            foreach (ail.net.parser.FsaState state in states)
            {
                if (!state.Marked)
                {
                    // add non-equivalent groups
                    ail.net.parser.FsaStateSet group = new ail.net.parser.FsaStateSet(GroupCounter.Next());
                    group.States.Add(state.Id, state);
                    xio_partition.Add(group.Id, group);
                }
            }

            ResetMarkedStates();
        }
Пример #3
0
        private void BuildPrimaryPartition(ref Hashtable xio_partition)
        {
            // builds primary partition, which consist of two groups: {F} anf {Q-F}
            ail.net.framework.Assert.NonNullReference(xio_partition, "xio_partition");

            xio_partition.Clear();

            ail.net.parser.FsaStateSet nf_states = new ail.net.parser.FsaStateSet(GroupCounter.Next()); // non-final states
            ail.net.parser.FsaStateSet fn_states = new ail.net.parser.FsaStateSet(GroupCounter.Next()); // final states

            xio_partition.Add(nf_states.Id, nf_states);                                                 // final states will be split and add later

            foreach (ail.net.parser.FsaState state in States.Values)
            {
                if (IsFinalState(state))
                {
                    fn_states.States.Add(state.Id, state);
                }
                else
                {
                    nf_states.States.Add(state.Id, state);
                }
            }

            // also, for lexical analyzer we should separate final states by tokens into different groups
            Hashtable subgroups = new Hashtable();

            ail.net.parser.FsaStateSet group     = new ail.net.parser.FsaStateSet(GroupCounter.Next());
            ail.net.parser.FsaState    pin_state = (ail.net.parser.FsaState)ail.net.framework.Functor.FirstElementOfCollection(fn_states.States.Values);

            group.States.Add(pin_state.Id, pin_state);
            subgroups.Add(group.Id, group);
_start:
            foreach (ail.net.parser.FsaState state in fn_states.States.Values)
            {
                if (state.Marked)
                {
                    continue;
                }

                ail.net.parser.FsaStateSet subgroup_to_add = null;

                // find subgroup it may belong to
                foreach (ail.net.parser.FsaStateSet subgroup in subgroups.Values)
                {
                    foreach (ail.net.parser.FsaState subgroup_state in subgroup.States.Values)
                    {
                        if (state.Token.Type == subgroup_state.Token.Type)
                        {
                            subgroup_to_add = subgroup;
                            break;
                        }
                    }

                    if (subgroup_to_add != (object)null)
                    {
                        break;
                    }
                }

                if (subgroup_to_add == (object)null) // not found - split
                {
                    ail.net.parser.FsaStateSet new_group = new ail.net.parser.FsaStateSet(GroupCounter.Next());

                    new_group.States.Add(state.Id, state);
                    subgroups.Add(new_group.Id, new_group);

                    state.Marked = true;

                    goto _start; // fortunately not so many final states :((
                }
                else
                {
                    if (!subgroup_to_add.States.Contains(state.Id))
                    {
                        subgroup_to_add.States.Add(state.Id, state);
                    }
                }
            }

            // clean up
_reset:
            foreach (ail.net.parser.FsaState state in fn_states.States.Values)
            {
                if (state.Marked)
                {
                    state.Marked = false;
                    fn_states.States.Remove(state.Id);
                    goto _reset;
                }
            }

            // insert subgroups
            foreach (ail.net.parser.FsaStateSet subgroup in subgroups.Values)
            {
                xio_partition.Add(subgroup.Id, subgroup);
            }
        }