/// <summary> /// Determinizes the specified automaton. /// </summary> /// <remarks> /// Complexity: exponential in number of states. /// </remarks> /// <param name="a">The automaton.</param> internal static void Determinize(Automaton a) { if (a.IsDeterministic || a.IsSingleton) { return; } var initialset = new HashSet <State>(); initialset.Add(a.Initial); BasicOperations.Determinize(a, initialset.ToList()); }
/// <summary> /// Accepts <code>min</code> or more concatenated repetitions of the language of the given /// automaton. /// </summary> /// <param name="a">The automaton.</param> /// <param name="min">The minimum concatenated repetitions of the language of the given /// automaton.</param> /// <returns>Returns an automaton that accepts <code>min</code> or more concatenated /// repetitions of the language of the given automaton. /// </returns> /// <remarks> /// Complexity: linear in number of states and in <code>min</code>. /// </remarks> internal static Automaton Repeat(Automaton a, int min) { if (min == 0) { return(BasicOperations.Repeat(a)); } var @as = new List <Automaton>(); while (min-- > 0) { @as.Add(a); } @as.Add(BasicOperations.Repeat(a)); return(BasicOperations.Concatenate(@as)); }
internal static Automaton Concatenate(Automaton a1, Automaton a2) { if (a1.IsSingleton && a2.IsSingleton) { return(BasicAutomata.MakeString(a1.Singleton + a2.Singleton)); } if (BasicOperations.IsEmpty(a1) || BasicOperations.IsEmpty(a2)) { return(BasicAutomata.MakeEmpty()); } bool deterministic = a1.IsSingleton && a2.IsDeterministic; if (a1 == a2) { a1 = a1.CloneExpanded(); a2 = a2.CloneExpanded(); } else { a1 = a1.CloneExpandedIfRequired(); a2 = a2.CloneExpandedIfRequired(); } foreach (State s in a1.GetAcceptStates()) { s.Accept = false; s.AddEpsilon(a2.Initial); } a1.IsDeterministic = deterministic; a1.ClearHashCode(); a1.CheckMinimizeAlways(); return(a1); }
private Automaton ToAutomaton( IDictionary <string, Automaton> automata, IAutomatonProvider automatonProvider, bool minimize) { IList <Automaton> list; Automaton a = null; switch (kind) { case Kind.RegexpUnion: list = new List <Automaton>(); this.FindLeaves(exp1, Kind.RegexpUnion, list, automata, automatonProvider, minimize); this.FindLeaves(exp2, Kind.RegexpUnion, list, automata, automatonProvider, minimize); a = BasicOperations.Union(list); a.Minimize(); break; case Kind.RegexpConcatenation: list = new List <Automaton>(); this.FindLeaves(exp1, Kind.RegexpConcatenation, list, automata, automatonProvider, minimize); this.FindLeaves(exp2, Kind.RegexpConcatenation, list, automata, automatonProvider, minimize); a = BasicOperations.Concatenate(list); a.Minimize(); break; case Kind.RegexpIntersection: a = exp1.ToAutomaton(automata, automatonProvider, minimize) .Intersection(exp2.ToAutomaton(automata, automatonProvider, minimize)); a.Minimize(); break; case Kind.RegexpOptional: a = exp1.ToAutomaton(automata, automatonProvider, minimize).Optional(); a.Minimize(); break; case Kind.RegexpRepeat: a = exp1.ToAutomaton(automata, automatonProvider, minimize).Repeat(); a.Minimize(); break; case Kind.RegexpRepeatMin: a = exp1.ToAutomaton(automata, automatonProvider, minimize).Repeat(min); a.Minimize(); break; case Kind.RegexpRepeatMinMax: a = exp1.ToAutomaton(automata, automatonProvider, minimize).Repeat(min, max); a.Minimize(); break; case Kind.RegexpComplement: a = exp1.ToAutomaton(automata, automatonProvider, minimize).Complement(); a.Minimize(); break; case Kind.RegexpChar: a = BasicAutomata.MakeChar(c); break; case Kind.RegexpCharRange: a = BasicAutomata.MakeCharRange(from, to); break; case Kind.RegexpAnyChar: a = BasicAutomata.MakeAnyChar(); break; case Kind.RegexpEmpty: a = BasicAutomata.MakeEmpty(); break; case Kind.RegexpString: a = BasicAutomata.MakeString(s); break; case Kind.RegexpAnyString: a = BasicAutomata.MakeAnyString(); break; case Kind.RegexpAutomaton: Automaton aa = null; if (automata != null) { automata.TryGetValue(s, out aa); } if (aa == null && automatonProvider != null) { try { aa = automatonProvider.GetAutomaton(s); } catch (IOException e) { throw new ArgumentException(string.Empty, e); } } if (aa == null) { throw new ArgumentException("'" + s + "' not found"); } a = aa.Clone(); // Always clone here (ignore allowMutate). break; case Kind.RegexpInterval: a = BasicAutomata.MakeInterval(min, max, digits); break; } return(a); }
internal bool Run(string s) { return(BasicOperations.Run(this, s)); }
internal Automaton Repeat(int min) { return(BasicOperations.Repeat(this, min)); }
internal Automaton Repeat() { return(BasicOperations.Repeat(this)); }
internal Automaton Optional() { return(BasicOperations.Optional(this)); }
internal bool IsEmptyString() { return(BasicOperations.IsEmptyString(this)); }
internal Automaton Intersection(Automaton a) { return(BasicOperations.Intersection(this, a)); }
internal void Determinize() { BasicOperations.Determinize(this); }
internal Automaton Concatenate(Automaton a) { return(BasicOperations.Concatenate(this, a)); }
internal Automaton Complement() { return(BasicOperations.Complement(this)); }
internal void AddEpsilons(ICollection <StatePair> pairs) { BasicOperations.AddEpsilons(this, pairs); }