public void RemoveTransition(ail.net.parser.FsaState xi_state, ail.net.parser.FsaTransition xi_transition) { ail.net.framework.Assert.NonNullReference(xi_state, "xi_state"); ail.net.framework.Assert.NonNullReference(xi_transition, "xi_transition"); ail.net.framework.Assert.Condition(States.Contains(xi_state.Id), "xi_state.Id"); ail.net.framework.Assert.Condition(xi_state.Transitions.Contains(xi_transition.Id), "xi_state.Transitions.Contains(xi_transition.Id)"); xi_state.Transitions.Remove(xi_transition.Id); }
private bool AreEqual(ail.net.parser.FsaState xi_state, ail.net.parser.FsaState xi_curr_state, Hashtable xi_partition) { ail.net.framework.Assert.NonNullReference(xi_state, "xi_state"); ail.net.framework.Assert.NonNullReference(xi_curr_state, "xi_curr_state"); ail.net.framework.Assert.NonNullReference(xi_partition, "xi_partition"); bool result = false; // loop on all predicates relevant for these two states only, // as automaton is deterministic every state has at most one transition with given predicate #if USE_STATE_PREDICATE_SET Hashtable predicates = CombinePredicates(xi_state, xi_curr_state); foreach (ail.net.parser.FsaTransitionPredicate predicate in predicates.Values) #else foreach (ail.net.parser.FsaTransitionPredicate predicate in Predicates.Values) #endif { ail.net.parser.FsaTransition t1 = xi_state.GetTransitionByPredicate(predicate); ail.net.parser.FsaTransition t2 = xi_curr_state.GetTransitionByPredicate(predicate); #if !USE_STATE_PREDICATE_SET if (t1 == (object)null && t2 == (object)null) // skip not relevant { continue; } #endif result = false; // reset if (t1 == (object)null || t2 == (object)null) { break; } // attempt to find group with these two states foreach (ail.net.parser.FsaStateSet group in xi_partition.Values) { if (group.States.Contains(t1.End) && group.States.Contains(t2.End)) { result = true; break; } } if (!result) { break; } } return(result); }
public ail.net.parser.FsaTransition GetTransitionByPredicate(ail.net.parser.FsaTransitionPredicate xi_predicate) { ail.net.framework.Assert.NonNullReference(xi_predicate, "xi_predicate"); ail.net.parser.FsaTransition result = null; foreach (ail.net.parser.FsaTransition transition in Transitions.Values) { if (transition.Predicate.Text == xi_predicate.Text) { result = transition; break; } } return(result); }
public ail.net.parser.FsaTransition AddTransition(int xi_start, int xi_end, string xi_predicate, char xi_switch_char, string xi_context, int xi_rank) { ail.net.framework.Assert.NonEmptyString(xi_predicate, "xi_predicate"); ail.net.parser.FsaTransition result = null; ail.net.parser.FsaState state = (ail.net.parser.FsaState)States[xi_start]; ail.net.framework.Assert.NonNullReference(state, "state"); int transition_id = TransitionCounter.Next(); result = new ail.net.parser.FsaTransition(transition_id, xi_start, xi_end, xi_predicate, xi_switch_char, xi_context, xi_rank); state.Transitions.Add(transition_id, result); if (!Predicates.Contains(xi_predicate)) { Predicates.Add(xi_predicate, result.Predicate); } return(result); }
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(); }
public ail.net.parser.Fsa Nfa2Dfa() { // Conversion of an NFA into a DFA (subset construction) // ..................................................... // Input: An NFA N. // Output: A DFA D accepting the same language. // Operations: // e-closure(s) is the set of NFA states reachable from s on e-transitions alone. // e-closure(T) is the union of e-closure(r) for all r in T. // move(T, a) is the set of NFA states to which there is a transition on input a from some NFA state in T. // // set the start state to e-closure(s0) and unmark it. // While there is an unmarked state T in Dstates do // Mark T // For each input symbol a do // If U := e-closure(move(T, a)); // If U is not in Dstates then // Add U as an unmarked state to Dstates; // Dtran(T, a) := U; // End; // End; ail.net.parser.Fsa result = new ail.net.parser.Fsa(); ArrayList dfa_states = new ArrayList(); // build pseudo dfa ail.net.parser.FsaStateSet start_dfa_state = CalculateStateEclosure(StartState); start_dfa_state.Id = dfa_states.Count; start_dfa_state.Marked = false; dfa_states.Add(start_dfa_state); bool proceed = false; for (;;) { IEnumerator dfa_state_enum = dfa_states.GetEnumerator(); while (dfa_state_enum.MoveNext()) { ail.net.parser.FsaStateSet dfa_state = (ail.net.parser.FsaStateSet)dfa_state_enum.Current; if (!dfa_state.Marked) { dfa_state.Marked = true; foreach (ail.net.parser.FsaTransitionPredicate predicate in Predicates.Values) { if (predicate.Text != ail.net.parser.FsaTransition.kEpsilonPredicate) { ail.net.parser.FsaStateSet move_set = CalculateMove(dfa_state, predicate.Text); if (move_set != (object)null) { ail.net.parser.FsaStateSet pseudo_dfa_state = CalculateEClosureFromMove(move_set); if (pseudo_dfa_state != (object)null && pseudo_dfa_state.States.Count > 0) { ail.net.parser.FsaStateSet new_dfa_state = HasDfaCompoundState(dfa_states, pseudo_dfa_state); if (new_dfa_state == (object)null) { new_dfa_state = pseudo_dfa_state; new_dfa_state.Id = dfa_states.Count; new_dfa_state.Marked = false; dfa_states.Add(new_dfa_state); dfa_state_enum = dfa_states.GetEnumerator(); // reset iterator } if (!dfa_state.Transitions.Contains(dfa_state.Transitions.Count)) { ail.net.parser.FsaTransition transition = new ail.net.parser.FsaTransition(dfa_state.Transitions.Count, dfa_state.Id, new_dfa_state.Id, predicate.Text, predicate.SwitchChar, predicate.Context, predicate.Rank); dfa_state.Transitions.Add(transition.Id, transition); } } } } } proceed = true; } } if (!proceed) { break; } proceed = false; } // populate states and final states foreach (ail.net.parser.FsaStateSet dfa_state in dfa_states) { ail.net.parser.FsaState state = result.AddState(dfa_state.Id); ail.net.framework.Assert.NonNullReference(state, "state"); foreach (ail.net.parser.FsaTransition transition in dfa_state.Transitions.Values) { result.AddTransition(transition.Start, transition.End, transition.Predicate.Text, transition.Predicate.SwitchChar, transition.Predicate.Context, transition.Predicate.Rank); } ail.net.parser.FsaState final_state = null; foreach (ail.net.parser.FsaState tmp_state in dfa_state.States.Values) { if (FinalStates.Contains(tmp_state.Id)) { ail.net.parser.FsaState org_state = (ail.net.parser.FsaState)States[tmp_state.Id]; ail.net.framework.Assert.NonNullReference(org_state, "org_state"); if (final_state == (object)null || org_state.Token.Priority > final_state.Token.Priority) { final_state = org_state; } } } if (final_state != (object)null) { result.AddFinalState(state, final_state.Token); } } result.StateCounter.Reset(States.Count); return(result); }