/// <summary> /// Adds a normal state to the set /// Traverses split states recursively until normal states they are connected to /// are found, then adds these states to the set /// </summary> /// <param name="set">The set to add the state to</param> /// <param name="state">The state to add to the set</param> private void AddStateToSet(HashSet<INFAState> set, INFAState state) { //If the state is a split state, traverse it recursively until the //real state is reached if (state.GetNFAType() == NFAStateType.Split) { AddStateToSet(set, ((NFASplitState)state).nextState1); AddStateToSet(set, ((NFASplitState)state).nextState2); } else set.Add(state); }
bool INFA.RemoveTransition(INFAState state, IEpsilonTransition epsilonTransition) => this.RemoveTransition((IRegexNFAState <T>)state, (IRegexFSMEpsilonTransition <T>)epsilonTransition);
/// <summary> /// Creates an NFA fragment from a given state /// </summary> /// <param name="state"></param> public NFAFragment(INFAState state) { startState = state; unboundStates = new List<INFAState>(); unboundStates.Add(state); }
/// <summary> /// Constructs a character-set NFA from a given character group /// </summary> /// <param name="characterGroup">A character group (bracketless) to construct an NFA from</param> public NFACharacterSet(string characterGroup) { //Initialize the parameters nextState = null; characters = new bool[256]; //If it's a single character, skip the character group parsing operation if (characterGroup.Length == 1) { characters[characterGroup[0]] = true; return; } //Parse the character group int currPos = 0; char currChar = ' '; while (currPos < characterGroup.Length) { //If we have reached the dash in the middle of e.g. A-Z if (characterGroup[currPos] == '-') { if (currChar < characterGroup[currPos + 1]) { //The NFA accepts all characters from the left of the dash (stored in currChar) //to the right (characterGroup[currPos + 1]) for (char i = currChar; i < characterGroup[currPos + 1]; i++) { characters[i] = true; } } //Move past the second limiting character in the group currPos += 2; } else { //If it's a simple character, add it to the accepted characters' group //and store it in case it turns out to be "A-Z" sequence currChar = characterGroup[currPos]; characters[currChar] = true; currPos++; } } }
/// <summary> /// Connects all unbound states of this NFA to the given state /// </summary> /// <param name="state">State to connect this NFA to</param> public void ConnectUnboundStates(INFAState state) { foreach (INFAState currState in unboundStates) { currState.Connect(state); } }
/// <summary> /// Creates an empty NFA fragment /// </summary> public NFAFragment() { startState = null; unboundStates = new List<INFAState>(); }
/// <summary> /// Dummy method used to make NFAMatchState conform to the INFAState interface /// </summary> /// <param name="toConnect"></param> public void Connect(INFAState toConnect) { }
/// <summary> /// Constructs a split NFA state with given outputs /// </summary> /// <param name="next1">The first output of the NFA</param> /// <param name="next2">The second output of the NFA</param> public NFASplitState(INFAState next1, INFAState next2) { nextState1 = next1; nextState2 = next2; }
/// <summary> /// Constructs an empty split NFA /// </summary> public NFASplitState() { nextState1 = null; nextState2 = null; }
/// <summary> /// Connects the output of the current NFA to the input of the specified NFA /// </summary> /// <param name="toConnect">The NFA to connect to</param> public void Connect(INFAState toConnect) { if (nextState1 == null) nextState1 = toConnect; if (nextState2 == null) nextState2 = toConnect; }
/// <summary> /// Connects the output of the current NFA to the input of the specified NFA /// </summary> /// <param name="toConnect">The NFA to connect to</param> public void Connect(INFAState toConnect) { if (nextState == null) nextState = toConnect; }