public void Add(Set key, AutomataState mapTo) { Set set = null; if (base.Contains(key)) { set = (Set)base[key]; } else { set = new Set(); } set.addElement(mapTo); base[key] = set; }
/*** add the transition between the start state "this" and the end state "endState", using 'trans_char', to the list of outgoing transition of this ***/ public void addOutgoingTransition(string trans_char, AutomataState endState) { Tuple<string, AutomataState> trans = new Tuple<string, AutomataState>(trans_char, endState); transitions.Add(trans); }
/*** Replace the endstate (with "newState") of which transitions s.t. endstate is equal to "oldState" ***/ public int replaceEndstateForTransitions(AutomataState oldState, AutomataState newState) { int count = 0; for (int i = 0; i < transitions.Count; i++) { if (transitions[i].Item2 == oldState) { transitions[i] = new Tuple<string, AutomataState>(transitions[i].Item1, newState); count++; } } return count; }
/*** Build states and transions of DFA starting from the start state of NFA, using subset construction algorithm. Return the start state of DFA.***/ private AutomataState NFAtoDFA(AutomataState Szero_NFA) { // 1) fill the 2nd and 3rd arguments Set setAllSym = new Set(); Set setAllState = new Set(); FillStatesAndSymbols(setAllState, setAllSym, Szero_NFA); setAllSym.removeElFromSet(RExpr_Parser.Tokens.EPSILON); Set epsClos = getEpsClosureFromState(Szero_NFA); AutomataState Szero_DFA = new AutomataState(); if (ExistFinalStateInSet(epsClos)) { // set the start state as also final state Szero_DFA.IsFinalState = true; } CreateNewDFAState(epsClos, Szero_DFA); // 2) Compute "subset construction" algorithm string transChar = ""; AutomataState T = null, U = null; Set epsClosureT = null, mvs = null; // main loop (breakable with null checking) while (true) { // until exists an unmarked state T T = getUnmarkedState(); if (T == null) break; // "Mark" this state markState(T); // get the EpsClosure of T epsClosureT = getEpsClosure(T); // for each symbol in the set of all symbols (inner for of the "construction set" algorithm) foreach (object obj in setAllSym) { transChar = obj.ToString(); mvs = getMoves(transChar, epsClosureT); if (mvs.NumOfElement != 0) { // U = E-clos(move(T,inputSym)) epsClos = getEpsClosureFromStateSet(mvs); U = FindDfaStateByEclosure(epsClos); // if in this set of NFA's states exists a final state, the set is a final state of DFA if (U == null) { U = new AutomataState(); if (ExistFinalStateInSet(epsClos)) { U.IsFinalState = true; } // add a new (unmarked) state CreateNewDFAState(epsClos, U); } // add to DFA transitions (T,transChar) -> U T.addOutgoingTransition(transChar, U); } } } return Szero_DFA; }
/*** Create a minimized version of the DFA (called DFAmin) ***/ private AutomataState MinimizeDFA(AutomataState Szero_DFA) { // 1) partition the DFS states (filling 2nd and 3rd arguments) Set transSymbols = new Set(); Set DFAstates = new Set(); FillStatesAndSymbols(DFAstates, transSymbols, Szero_DFA); ArrayList arr = createDFASets(DFAstates, transSymbols); // 2) through all the groups and select a pivot for each group. AutomataState stateStartReducedDfa = null; foreach (object objGroup in arr) { Set setGroup = (Set)objGroup; // check final states SzeroDFA in the group bool finalStInGroup = ExistFinalStateInSet(setGroup); bool startDFAinGroup = setGroup.Contains(Szero_DFA); AutomataState pivotState = (AutomataState)setGroup[0]; if (startDFAinGroup) { stateStartReducedDfa = pivotState; } if (finalStInGroup) { pivotState.IsFinalState = true; } // if there are only once element, continue loop if (setGroup.NumOfElement == 1) { continue; } // 3) [innerLoop] remove the pivot from its group and replace all the references of the remaining member of the group setGroup.removeElFromSet(pivotState); // state to be replaced with the group of pivot AutomataState stateToBeReplaced = null; int numOfReplace = 0; foreach (object objStateToReplaced in setGroup) { stateToBeReplaced = (AutomataState)objStateToReplaced; DFAstates.removeElFromSet(stateToBeReplaced); foreach (object objState in DFAstates) { numOfReplace = numOfReplace + ((AutomataState)objState).replaceEndstateForTransitions(stateToBeReplaced, pivotState); } } } // 4) finally can remove all "close states" for (int n = 0; n < DFAstates.Count; n++) { AutomataState state = (AutomataState)DFAstates[n]; if (state.isAClosedState()) { DFAstates.RemoveAt(n); continue; } } return stateStartReducedDfa; }
/*** Get all the states moves as above but starting from a single state ***/ private Set getMoves(string trans_chr, AutomataState state) { Set s = new Set(); List<AutomataState> lTrns = state.getAllDestStatesWithStringTransaction(trans_chr); if (lTrns != null && lTrns.Count > 0) { s.addElementRange(lTrns.ToArray()); } return s; }
/*** Finds all states that are "toStates" by a startState via E-transition ***/ private Set getEpsClosureFromState(AutomataState startState) { // set for dividing states Set processedStates = new Set(); Set unprocessedStates = new Set(); // add start state to unprocessed set unprocessedStates.addElement(startState); // until exists unprocessed states while (unprocessedStates.Count > 0) { // get all "toState" of E-transitions from "state" AutomataState state = (AutomataState)unprocessedStates[0]; List<AutomataState> l_trns = state.getAllDestStatesWithStringTransaction(RExpr_Parser.Tokens.EPSILON); // process state processedStates.addElement(state); unprocessedStates.removeElFromSet(state); if (l_trns != null && l_trns.Count > 0) { foreach (AutomataState Estate in l_trns) { if (!processedStates.Contains(Estate)) { unprocessedStates.addElement(Estate); } } } } return processedStates; }
/*** Find in which set of the "arrayOfSet" the state "state" is contained. Return null if there are no set that contains "state". ***/ private Set findInWhichSet(ArrayList arrayOfSet, AutomataState state) { foreach (object objSet in arrayOfSet) { Set set = (Set)objSet; if (set.Contains(state)) { return set; } } return null; }
/*** Fill the sets "allStates" and "allSym" (respectivly) with all the states and the symbols of the automata (discriminate NFA-DFA-DFAmin from starting state) ***/ private static void FillStatesAndSymbols(Set allStates, Set allSym, AutomataState stateStart) { Set unprocessedStates = new Set(); // add first state to unprocessed unprocessedStates.addElement(stateStart); // untile the are unprocessed states while (unprocessedStates.Count > 0) { AutomataState state = (AutomataState)unprocessedStates[0]; allStates.addElement(state); unprocessedStates.removeElFromSet(state); // for each transition char of transitions of "state" foreach (string s in state.getAllTransitionsChars()) { allSym.addElement(s); // get all "Tostate"s from state by "s" List<AutomataState> l_trns = state.getAllDestStatesWithStringTransaction(s); if (l_trns != null && l_trns.Count > 0) { foreach (AutomataState EpsState in l_trns) { if (!allStates.Contains(EpsState)) { unprocessedStates.addElement(EpsState); } } } } } }
/*** check if the transition from "currState" is caused by "." ***/ private static bool checkSomeChar(AutomataState currState) { return currState.getExactTransition(RExpr_Parser.Tokens.TOK_SOMECHAR_TRANS) != null; }
/*** Given a string contains a regular expression, perform the parse of it. If the parse is positive, produces a Minimum DFA model. Otherwise throw SyntaxException. ***/ public StringBuilder ParseRegexAndCreateAutomata(Stopwatch timer, string regex) { StringBuilder statistics_s = new StringBuilder(); this.isCompiled = false; // set the global start id for states to 0 AutomataState.resetStatesGlobalCounter(); // reset hashtable for DFA DFAStatesTable.Clear(); // start timing for parsing timer.Reset(); timer.Start(); // invoke the parser (it can generate SyntaxException) and set the parsed string as Text of "label_formatted_regex" in Main form string parsed_regex = RExpr_parser.ParseRExpr(regex); // arrange parsed regex string applying postfixing tecnique string arranged_regex = ArrangeRegex(parsed_regex); /*** 1) Create a NFA starting from re-arranged parsed regex ***/ AutomataState Szero_NFA = BuildNFA(arranged_regex); /*** 2) Create a DFA starting from NFA start state ***/ AutomataState.resetStatesGlobalCounter(); AutomataState Szero_DFA = NFAtoDFA(Szero_NFA); /*** 3) Create min DFA from DFA start state ***/ AutomataState SzeroDFAmin = MinimizeDFA(Szero_DFA); Sz_DFAmin = SzeroDFAmin; // stop timing for parsing timer.Stop(); return statistics_s; }
/*** Mark the passed state of the hashtable ***/ public void markState(AutomataState s) { ((AutomataDFAState)DFAStatesTable[s]).isMark = true; }
/*** Given an input state, get it E-closure. ***/ public Set getEpsClosure(AutomataState state) { AutomataDFAState s = (AutomataDFAState)DFAStatesTable[state]; return (s == null) ? null : s.EpsClos; }
/*** Add a new DFA state to the hashtable ***/ public void CreateNewDFAState(Set Eclos, AutomataState DFAstate) { AutomataDFAState stateRecord = new AutomataDFAState(); stateRecord.EpsClos = Eclos; DFAStatesTable[DFAstate] = stateRecord; }