/// <summary> /// Builds an automaton equivalent to the regex s[0]s[1] ... s[r.Length-1], /// returns the automaton accepting only the empty word when s is empty. /// </summary> public Automaton <S> MkSeq(params S[] s) { if (s.Length == 0) { return(MkEmptyWord()); } bool start = isBeg; bool end = isEnd; //sequence of characters //string sequence = node._str; int count = s.Length; //bool ignoreCase = ((node._options & RegexOptions.IgnoreCase) != 0); int initialstate = nodeId; nodeId = nodeId + count + 1; int finalstate = initialstate + count; int[] finalstates = new int[] { finalstate }; var moves = new List <Move <S> >(); for (int i = 0; i < count; i++) { moves.Add(Move <S> .Create(initialstate + i, initialstate + i + 1, s[i])); } Automaton <S> res = Automaton <S> .Create(this.solver, initialstate, finalstates, moves); res.isDeterministic = true; if (start) //may start with any characters { res.AddMove(Move <S> .Create(initialstate, initialstate, solver.True)); res.isDeterministic = false; } if (end) //may end with any characters { res.AddMove(Move <S> .Create(finalstate, finalstate, solver.True)); } res.isEpsilonFree = true; return(res); }
private Automaton <S> MakeKleeneClosure(Automaton <S> sfa) { if (sfa.IsEmpty || sfa.IsEpsilon) { return(this.epsilon); } if (sfa.IsKleeneClosure()) { return(sfa); } if (sfa.DoesNotContainWordBoundaries && sfa.InitialStateIsSource && sfa.HasSingleFinalSink) { //common case, avoid epsilons in this case //just destructively make the final state to be the initial state sfa.RenameInitialState(sfa.FinalState); return(sfa); } int origInitState = sfa.InitialState; if (!sfa.IsFinalState(sfa.InitialState))//the initial state is not final { if (sfa.InitialStateIsSource) { //make the current initial state final sfa.MakeInitialStateFinal(); } else { //add a new initial state that is also final sfa.AddNewInitialStateThatIsFinal(this.MkStateId()); } } //add epsilon transitions from final states to the original initial state foreach (int state in sfa.GetFinalStates()) { if (state != sfa.InitialState && state != origInitState) { sfa.AddMove(Move <S> .Epsilon(state, origInitState)); } } //epsilon loops might have been created, remove them var sfa1 = sfa.RemoveEpsilonLoops(); if (!sfa.DoesNotContainWordBoundaries) { sfa1.AddWordBoundaries(sfa.EnumerateWordBoundaries()); } return(sfa1); }