/// <summary> /// Initializer all fields, used also by deserializer of SymbolicRegexMatcher /// </summary> private void InitilizeFields(ICharAlgebra <S> solver) { this.solver = solver; this.nothing = SymbolicRegexNode <S> .MkFalse(this, solver.False); this.dot = SymbolicRegexNode <S> .MkTrue(this, solver.True); this.dotStar = SymbolicRegexNode <S> .MkDotStar(this, this.dot); this.newLine = SymbolicRegexNode <S> .MkNewline(this, solver.MkCharConstraint('\n')); this.bolRegex = SymbolicRegexNode <S> .MkLoop(this, SymbolicRegexNode <S> .MkConcat(this, this.dotStar, this.newLine), 0, 1); this.eolRegex = SymbolicRegexNode <S> .MkLoop(this, SymbolicRegexNode <S> .MkConcat(this, this.newLine, this.dotStar), 0, 1); // --- initialize caches --- this.singletonCache[this.solver.False] = this.nothing; this.singletonCache[this.newLine.set] = this.newLine; this.singletonCache[this.solver.True] = this.dot; //--- this.nodeCache[this.nothing] = this.nothing; this.nodeCache[this.dot] = this.dot; this.nodeCache[this.dotStar] = this.dotStar; this.nodeCache[this.newLine] = this.newLine; this.nodeCache[this.bolRegex] = this.bolRegex; this.nodeCache[this.eolRegex] = this.eolRegex; }
/// <summary> /// Make a concatenation of given regexes, if any regex is nothing then return nothing, eliminate /// intermediate epsilons /// </summary> public SymbolicRegexNode <S> MkConcat(params SymbolicRegexNode <S>[] regexes) { if (regexes.Length == 0) { return(this.epsilon); } var sr = regexes[regexes.Length - 1]; if (sr == this.nothing) { return(this.nothing); } else { //exclude epsilons from the concatenation for (int i = regexes.Length - 2; i >= 0; i--) { if (regexes[i] == this.nothing) { return(this.nothing); } else if (sr.IsEpsilon) { sr = regexes[i]; } else if (!regexes[i].IsEpsilon) { sr = SymbolicRegexNode <S> .MkConcat(this, regexes[i], sr); } } return(sr); } }
/// <summary> /// Make a concatenation of given regexes, if any regex is nothing then return nothing, eliminate /// intermediate epsilons, if toplevel, add watchdog at the end /// </summary> public SymbolicRegexNode <S> MkConcat(SymbolicRegexNode <S>[] regexes, bool topLevel) { if (regexes.Length == 0) { return(this.epsilon); } var sr = this.epsilon; int length = CalculateFixedLength(regexes); if (topLevel && length >= 0) { sr = MkWatchDog(length); } //exclude epsilons from the concatenation for (int i = regexes.Length - 1; i >= 0; i--) { if (regexes[i] == this.nothing) { return(this.nothing); } else if (sr.IsEpsilon) { sr = regexes[i]; } else if (!regexes[i].IsEpsilon) { sr = SymbolicRegexNode <S> .MkConcat(this, regexes[i], sr); } } return(sr); }
/// <summary> /// Make a concatenation of given regexes, if any regex is nothing then return nothing, eliminate /// intermediate epsilons /// </summary> public SymbolicRegexNode <S> MkConcat(SymbolicRegexNode <S> node1, SymbolicRegexNode <S> node2) { if (node1.IsEpsilon) { return(node2); } else if (node2.IsEpsilon) { return(node1); } else { return(SymbolicRegexNode <S> .MkConcat(this, node1, node2)); } }
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(); } }