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(); } }
/// <summary> /// Make an if-then-else regex (?(cond)left|right), /// or create it as conjuction if right is false /// </summary> /// <param name="cond">condition</param> /// <param name="left">true case</param> /// <param name="right">false case</param> /// <returns></returns> public SymbolicRegexNode <S> MkIfThenElse(SymbolicRegexNode <S> cond, SymbolicRegexNode <S> left, SymbolicRegexNode <S> right) { return(SymbolicRegexNode <S> .MkIfThenElse(this, cond, left, right)); }
internal SymbolicRegexNode <S> Parse(string s, int i, out int i_next) { switch (s[i]) { case '.': { #region . i_next = i + 1; return(this.dot); #endregion } case '[': { #region parse singleton int j = s.IndexOf(']', i); var p = solver.DeserializePredicate(s.Substring(i + 1, j - (i + 1))); var node = this.MkSingleton(p); //SymbolicRegexNode<S> node; //var seq_str = s.Substring(i + 1, j - (i + 1)); //var preds_str = seq_str.Split(';'); //var preds = Array.ConvertAll(preds_str, solver.DeserializePredicate); //node = this.MkSequence(preds); 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, false); i_next = n + 1; return(node); #endregion } case 'Z': //Z(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, true); i_next = n + 1; return(node); #endregion } case 'S': { #region concatenation int n; SymbolicRegexNode <S>[] nodes = ParseSequence(s, i + 2, out n); var concat = this.MkConcat(nodes, false); i_next = n; return(concat); #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 end anchor i_next = i + 1; return(this.endAnchor); #endregion } case '#': { #region end of sequence anchor int j = s.IndexOf(')', i + 2); int length = int.Parse(s.Substring(i + 2, j - (i + 2))); i_next = j + 1; return(SymbolicRegexNode <S> .MkWatchDog(this, length)); #endregion } default: throw new NotImplementedException(); } }