/// <summary> /// Make a singleton sequence regex /// </summary> public SymbolicRegexNode <S> MkSingleton(S set) { SymbolicRegexNode <S> res; if (!singletonCache.TryGetValue(set, out res)) { res = SymbolicRegexNode <S> .MkSingleton(this, set); singletonCache[set] = res; } return(res); }
internal SymbolicRegexNode <S> Parse(string s, int i, out int i_next) { switch (s[i]) { case '.': { #region character class of all characters i_next = i + 1; return(this.dot); #endregion } case '[': { #region parse character class if (s[i + 1] == ']') { i_next = i + 2; return(this.nothing); } else { int j = s.IndexOf(']', i); int[] atomIds = Array.ConvertAll(s.Substring(i + 1, j - (i + 1)).Split(','), x => int.Parse(x)); S[] bva = Array.ConvertAll(atomIds, id => this.solver.GetPartition()[id]); var bv = this.solver.MkOr(bva); SymbolicRegexNode <S> node; if (!this.singletonCache.TryGetValue(bv, out node)) { node = SymbolicRegexNode <S> .MkSingleton(this, bv); this.singletonCache[bv] = node; } i_next = j + 1; return(node); } #endregion } case 'E': { #region Epsilon i_next = i + 1; return(this.epsilon); #endregion } case 'L': //L(l,u,body) for body{l,u} u may be * { #region Loop int j = s.IndexOf(',', i + 2); int lower = int.Parse(s.Substring(i + 2, j - (i + 2))); int upper = int.MaxValue; if (s[j + 1] == '*') { j = j + 3; } else { int k = s.IndexOf(',', j + 1); upper = int.Parse(s.Substring(j + 1, k - (j + 1))); j = k + 1; } int n; var body = Parse(s, j, out n); var node = SymbolicRegexNode <S> .MkLoop(this, body, lower, upper); i_next = n + 1; return(node); #endregion } case 'S': //binary concat S(R1,R2) { #region concatenation int n; var first = Parse(s, i + 2, out n); int m; var second = Parse(s, n + 1, out m); var seq = SymbolicRegexNode <S> .MkConcat(this, first, second); i_next = m + 1; return(seq); #endregion } case 'C': //conjunction C(R1,R2,...,Rk) { #region conjunction int n; SymbolicRegexNode <S>[] nodes = ParseSequence(s, i + 2, out n); var conj = SymbolicRegexNode <S> .MkAnd(this, nodes); i_next = n; return(conj); #endregion } case 'D': //Disjunction D(R1,R2,...,Rk) { #region disjunction int n; SymbolicRegexNode <S>[] nodes = ParseSequence(s, i + 2, out n); var disj = SymbolicRegexNode <S> .MkOr(this, nodes); i_next = n; return(disj); #endregion } case 'I': //if then else I(x,y,z) { #region ITE int n; var cond = Parse(s, i + 2, out n); int m; var first = Parse(s, n + 1, out m); int k; var second = Parse(s, m + 1, out k); var ite = SymbolicRegexNode <S> .MkIfThenElse(this, cond, first, second); i_next = k + 1; return(ite); #endregion } case '^': { #region start anchor i_next = i + 1; return(this.startAnchor); #endregion } case '$': { #region start anchor i_next = i + 1; return(this.endAnchor); #endregion } default: throw new NotImplementedException(); } }