예제 #1
0
        // 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)));
        }
예제 #2
0
        // 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()));
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 // epsi^a = empty ?
 public override RegEx <T> Derivative(T c)
 {
     return(RegExFactory.Empty <T>());
 }
예제 #8
0
 // [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>());
 }
예제 #9
0
 // star(X)^a = concat(X^a, star(X))
 public override RegEx <T> Derivative(T c)
 {
     return(RegExFactory.Concat(Regex.Derivative(c), RegExFactory.Star(Regex)));
 }
예제 #10
0
 // (~X)^a = ~(X^a)
 public override RegEx <T> Derivative(T c)
 {
     return(RegExFactory.Complement(Regex.Derivative(c)));
 }
예제 #11
0
 private static RegEx <char> SingleChar(char c)
 {
     return(RegExFactory.Range(c, (char)(c + 1)));
 }
예제 #12
0
 private static RegEx <char> Sanitize(RegEx <char> result)
 {
     return(RegExFactory.Intersection(result, RegExFactory.Star(CharactersClasses.print)));
 }
예제 #13
0
        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);
        }