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 (this.kind) { case Kind.RegexpUnion: list = new List <Automaton>(); this.FindLeaves(this.exp1, Kind.RegexpUnion, list, automata, automatonProvider, minimize); this.FindLeaves(this.exp2, Kind.RegexpUnion, list, automata, automatonProvider, minimize); a = BasicOperations.Union(list); a.Minimize(); break; case Kind.RegexpConcatenation: list = new List <Automaton>(); this.FindLeaves(this.exp1, Kind.RegexpConcatenation, list, automata, automatonProvider, minimize); this.FindLeaves(this.exp2, Kind.RegexpConcatenation, list, automata, automatonProvider, minimize); a = BasicOperations.Concatenate(list); a.Minimize(); break; case Kind.RegexpIntersection: a = this.exp1.ToAutomaton(automata, automatonProvider, minimize) .Intersection(this.exp2.ToAutomaton(automata, automatonProvider, minimize)); a.Minimize(); break; case Kind.RegexpOptional: a = this.exp1.ToAutomaton(automata, automatonProvider, minimize).Optional(); a.Minimize(); break; case Kind.RegexpRepeat: a = this.exp1.ToAutomaton(automata, automatonProvider, minimize).Repeat(); a.Minimize(); break; case Kind.RegexpRepeatMin: a = this.exp1.ToAutomaton(automata, automatonProvider, minimize).Repeat(this.min); a.Minimize(); break; case Kind.RegexpRepeatMinMax: a = this.exp1.ToAutomaton(automata, automatonProvider, minimize).Repeat(this.min, this.max); a.Minimize(); break; case Kind.RegexpComplement: a = this.exp1.ToAutomaton(automata, automatonProvider, minimize).Complement(); a.Minimize(); break; case Kind.RegexpChar: a = BasicAutomata.MakeChar(this.c); break; case Kind.RegexpCharRange: a = BasicAutomata.MakeCharRange(this.@from, this.to); break; case Kind.RegexpAnyChar: a = BasicAutomata.MakeAnyChar(); break; case Kind.RegexpEmpty: a = BasicAutomata.MakeEmpty(); break; case Kind.RegexpString: a = BasicAutomata.MakeString(this.s); break; case Kind.RegexpAnyString: a = BasicAutomata.MakeAnyString(); break; case Kind.RegexpAutomaton: Automaton aa = null; if (automata != null) { automata.TryGetValue(this.s, out aa); } if (aa == null && automatonProvider != null) { try { aa = automatonProvider.GetAutomaton(this.s); } catch (IOException e) { throw new ArgumentException(string.Empty, e); } } if (aa == null) { throw new ArgumentException("'" + this.s + "' not found"); } a = aa.Clone(); // Always clone here (ignore allowMutate). break; case Kind.RegexpInterval: a = BasicAutomata.MakeInterval(this.min, this.max, this.digits); break; } return(a); }
internal static Automaton MakeString(string s) { return(BasicAutomata.MakeString(s)); }
internal static Automaton Concatenate(IList <Automaton> l) { if (l.Count == 0) { return(BasicAutomata.MakeEmptyString()); } bool allSingleton = l.All(a => a.IsSingleton); if (allSingleton) { var b = new StringBuilder(); foreach (Automaton a in l) { b.Append(a.Singleton); } return(BasicAutomata.MakeString(b.ToString())); } else { if (l.Any(a => a.IsEmpty)) { return(BasicAutomata.MakeEmpty()); } var ids = new HashSet <int>(); foreach (Automaton a in l) { ids.Add(RuntimeHelpers.GetHashCode(a)); } bool hasAliases = ids.Count != l.Count; Automaton b = l[0]; b = hasAliases ? b.CloneExpanded() : b.CloneExpandedIfRequired(); var ac = b.GetAcceptStates(); bool first = true; foreach (Automaton a in l) { if (first) { first = false; } else { if (a.IsEmptyString()) { continue; } Automaton aa = a; aa = hasAliases ? aa.CloneExpanded() : aa.CloneExpandedIfRequired(); HashSet <State> ns = aa.GetAcceptStates(); foreach (State s in ac) { s.Accept = false; s.AddEpsilon(aa.Initial); if (s.Accept) { ns.Add(s); } } ac = ns; } } b.IsDeterministic = false; b.ClearHashCode(); b.CheckMinimizeAlways(); return(b); } }