/// <summary>
        /// Compiles this regex and possibly other regexes into a common symbolic regex representing their intersection
        /// </summary>
        /// <param name="regex">this regex</param>
        /// <param name="regexes">more regexes to intersect with</param>
        /// <param name="keepAnchors">if false missing anchors are replaced by .* else just omitted</param>
        /// <param name="unwindLowerBounds">if true then lower bounds of loops are unwound</param>
        /// <returns></returns>
        public static RegexMatcher Compile(this Regex regex, bool keepAnchors, bool unwindLowerBounds, params Regex[] regexes)
        {
            if (context == null)
            {
                context = new CharSetSolver();
            }

            var first  = context.RegexConverter.ConvertToSymbolicRegex(regex, keepAnchors, unwindLowerBounds);
            var others = Array.ConvertAll(regexes, r => context.RegexConverter.ConvertToSymbolicRegex(r, keepAnchors, unwindLowerBounds));
            var all    = new SymbolicRegexNode <BDD> [1 + regexes.Length];

            all[0] = first;
            for (int i = 1; i <= others.Length; i++)
            {
                all[i] = others[i - 1];
            }
            var          srBuilder = context.RegexConverter.srBuilder;
            var          conj      = srBuilder.MkAnd(all);
            var          partition = conj.ComputeMinterms();
            RegexMatcher matcher;

            if (partition.Length > 64)
            {
                //more than 64 bits needed to represent a set
                matcher = new SymbolicRegexBV(conj, context, partition);
            }
            else
            {
                //enough to use 64 bits
                matcher = new SymbolicRegexUInt64(conj, context, partition);
            }
            return(matcher);
        }
Beispiel #2
0
        /// <summary>
        /// Compiles this regex and possibly other regexes into a common symbolic regex representing their intersection
        /// </summary>
        /// <param name="regex">this regex</param>
        /// <param name="regexes">more regexes to intersect with</param>
        /// <param name="keepAnchors">if false missing anchors are replaced by .* else just omitted</param>
        /// <param name="unwindLowerBounds">if true then lower bounds of loops are unwound</param>
        /// <returns></returns>
        public static RegexMatcher Compile(this Regex regex, bool keepAnchors, bool unwindLowerBounds, bool isMatchOnly = false, params Regex[] regexes)
        {
            //first test if this regex is a simple string, i.e., a toplevel multi-node
            RegexTree rt = RegexParser.Parse(regex.ToString(), regex.Options);

            if (regexes.Length == 0)
            {
                if (rt._root._type == RegexNode.Capture && rt._root.Child(0)._type == RegexNode.Multi)
                {
                    //this is an explicit string
                    var pattern = rt._root.Child(0)._str;
                    return(new FixedStringMatcher(pattern, (regex.Options & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase));
                }
            }

            if (context == null)
            {
                context = new CharSetSolver();
            }

            var first = context.RegexConverter.ConvertToSymbolicRegex(rt._root, keepAnchors, unwindLowerBounds);

            if (!isMatchOnly && first.CheckIfContainsLazyLoop() && !first.CheckIfAllLoopsAreLazy())
            {
                throw new AutomataException("Match generation with mixed lazy and eager loops currently not supported.");
            }

            var others = Array.ConvertAll(regexes, r => context.RegexConverter.ConvertToSymbolicRegex(r, keepAnchors, unwindLowerBounds));
            var all    = new SymbolicRegexNode <BDD> [1 + regexes.Length];

            all[0] = first;
            for (int i = 1; i <= others.Length; i++)
            {
                all[i] = others[i - 1];
            }
            var          srBuilder = context.RegexConverter.srBuilder;
            var          conj      = srBuilder.MkAnd(all);
            var          partition = conj.ComputeMinterms();
            RegexMatcher matcher;

            if (partition.Length > 64)
            {
                //more than 64 bits needed to represent a set
                matcher = new SymbolicRegexBV(conj, context, partition);
            }
            else
            {
                //enough to use 64 bits
                matcher = new SymbolicRegexUInt64(conj, context, partition);
            }
            return(matcher);
        }