// return (R[i])(R[i+1])....(R[len-1]) private RegEx <T> ConcatRegexes(int depth) { if (depth == Regexes.Length - 1) { return(Regexes [depth]); } return(RegExFactory.Concat(Regexes [depth], ConcatRegexes(depth + 1))); }
// inter( X1, ... )^a = inter( X1^a, ... ) public override RegEx <T> Derivative(T c) { var derivatives = new List <RegEx <T> >(); foreach (var i in Regexes) { derivatives.Add(i.Derivative(c)); } return(RegExFactory.Intersection(derivatives.ToArray())); }
private static RegEx <char> ParseConcat() { var left = ParseStar(); if (left == null) { return(null); } var right = ParseConcat(); if (right != null) { return(RegExFactory.Concat(left, right)); } return(left); }
private RegEx <T> ComputeDerivative(int depth, T c) { // the last one if (depth == Regexes.Length - 1) { return(Regexes[depth].Derivative(c)); } // (R[i])^a(R[i+1]).... var this_level = RegExFactory.Concat( Regexes [depth].Derivative(c), ConcatRegexes(depth + 1) ); // first can be skipped if (Regexes [depth].HasEpsilon()) { return(RegExFactory.Union(this_level, ComputeDerivative(depth + 1, c))); } // cannot be skipped return(this_level); }
private static RegEx <char> ParseBinaryOperators() { var left = ParseConcat(); bool union = false, intersection = false; union |= HasPrefix("|"); intersection |= HasPrefix("&"); if (union || intersection) { Eat(1); var right = ParseBinaryOperators(); if (right == null) { throw new ParseError("Missed one of the union/intersection argument."); } return(union ? RegExFactory.Union(left, right) : RegExFactory.Intersection(left, right)); } return(left); }
private static RegEx <char> ParseStar() { var left = ParseAtom(); if (HasPrefix("*") || HasPrefix("+")) { bool star = false; while (HasPrefix("*") || HasPrefix("+")) { star |= HasPrefix("+"); Eat(1); } if (left == null) { throw new ParseError("Unassigned +/-."); } return(star ? RegExFactory.Concat(left, RegExFactory.Star(left)) : RegExFactory.Star(left)); } return(left); }
// epsi^a = empty ? public override RegEx <T> Derivative(T c) { return(RegExFactory.Empty <T>()); }
// [a...) = sum( {a}, {a+1}, {a+2}, ... ) // [a...)^x = sum( {a}, ... )^x = sum( {a}^x, {a+1}^x, ... ) // = epsilon if x >= a else empty public override RegEx <T> Derivative(T c) { return(Character.CompareTo(c) <= 0 ? RegExFactory.Epsilon <T>() : RegExFactory.Empty <T>()); }
// star(X)^a = concat(X^a, star(X)) public override RegEx <T> Derivative(T c) { return(RegExFactory.Concat(Regex.Derivative(c), RegExFactory.Star(Regex))); }
// (~X)^a = ~(X^a) public override RegEx <T> Derivative(T c) { return(RegExFactory.Complement(Regex.Derivative(c))); }
private static RegEx <char> SingleChar(char c) { return(RegExFactory.Range(c, (char)(c + 1))); }
private static RegEx <char> Sanitize(RegEx <char> result) { return(RegExFactory.Intersection(result, RegExFactory.Star(CharactersClasses.print))); }
private static RegEx <char> ParseAtom() { if (HasPrefix("[")) { Eat(1); bool complement = false; if (HasPrefix("^")) { Eat(1); complement = true; } RegEx <char> atom = null; if (HasPrefix(":digit:")) { atom = CharactersClasses.digit; } if (HasPrefix(":print:")) { atom = CharactersClasses.print; } if (HasPrefix(":space:")) { atom = CharactersClasses.space; } if (atom == null) { List <RegEx <char> > chars = new List <RegEx <char> > (); char ch; while ((ch = Peek()) != ']') { if (ch.Equals('\\')) { Accept("]"); chars.Add(SingleChar(']')); } else { chars.Add(SingleChar(ch)); } } atom = RegExFactory.Union(chars.ToArray()); } else { Eat(7); Accept("]"); } if (complement) { return(RegExFactory.Intersection(RegExFactory.Range((char)0), RegExFactory.Complement(atom))); } else { return(atom); } } if (HasPrefix(".")) { Eat(1); return(RegExFactory.Range((char)0)); } if (HasPrefix("(")) { Eat(1); var node = ParseBinaryOperators(); if (node == null) { throw new ParseError("Parentheses around the null expression."); } Accept(")"); return(node); } if (HasPrefix("^")) { Eat(1); var node = ParseAtom(); if (node == null) { throw new ParseError("Unassigned ^."); } return(RegExFactory.Complement(node)); } if (HasPrefix("\\")) { Eat(1); char a = Peek(); if (!specialCharacters.Contains("" + a)) { throw new ParseError("Special character required."); } return(SingleChar(a)); } if (HasNext()) { var a = Peek(); if (specialCharacters.Contains("" + a)) { --head; return(null); } return(SingleChar(a)); } return(null); }