Example #1
0
            public DfaMatchingState <TSetType> TakeTransition(
                SymbolicRegexMatcher <TSetType> matcher, DfaMatchingState <TSetType> currentStates, int mintermId, TSetType minterm)
            {
                if (currentStates.Node.Kind != SymbolicRegexKind.Or)
                {
                    // Fall back to Brzozowski when the state is not a disjunction.
                    return(default(BrzozowskiTransition).TakeTransition(matcher, currentStates, mintermId, minterm));
                }

                SymbolicRegexBuilder <TSetType> builder = matcher._builder;

                Debug.Assert(builder._delta is not null);

                SymbolicRegexNode <TSetType> union = builder._nothing;
                uint kind = 0;

                // Produce the new list of states from the current list, considering transitions from members one at a time.
                Debug.Assert(currentStates.Node._alts is not null);
                foreach (SymbolicRegexNode <TSetType> oneState in currentStates.Node._alts)
                {
                    DfaMatchingState <TSetType> nextStates = builder.MkState(oneState, currentStates.PrevCharKind);

                    int offset = (nextStates.Id << builder._mintermsCount) | mintermId;
                    DfaMatchingState <TSetType> p = Volatile.Read(ref builder._delta[offset]) ?? matcher.CreateNewTransition(nextStates, minterm, offset);

                    // Observe that if p.Node is an Or it will be flattened.
                    union = builder.MkOr2(union, p.Node);

                    // kind is just the kind of the partition.
                    kind = p.PrevCharKind;
                }

                return(builder.MkState(union, kind, true));
            }
Example #2
0
        /// <summary>Initializes the factory.</summary>
        public SymbolicRegexRunnerFactory(RegexTree regexTree, RegexOptions options, TimeSpan matchTimeout)
        {
            Debug.Assert((options & (RegexOptions.RightToLeft | RegexOptions.ECMAScript)) == 0);

            var charSetSolver = new CharSetSolver();
            var bddBuilder    = new SymbolicRegexBuilder <BDD>(charSetSolver, charSetSolver);
            var converter     = new RegexNodeConverter(bddBuilder, regexTree.CaptureNumberSparseMapping);

            SymbolicRegexNode <BDD> rootNode = converter.ConvertToSymbolicRegexNode(regexTree.Root);

            // Determine if the root node is supported for safe handling
            int threshold = SymbolicRegexThresholds.GetSymbolicRegexSafeSizeThreshold();

            Debug.Assert(threshold > 0);

            // Skip the threshold check if the threshold equals int.MaxValue
            if (threshold != int.MaxValue)
            {
                int size = rootNode.EstimateNfaSize();
                if (size > threshold)
                {
                    throw new NotSupportedException(SR.Format(SR.NotSupported_NonBacktrackingUnsafeSize, size, threshold));
                }
            }

            rootNode = rootNode.AddFixedLengthMarkers();
            BDD[] minterms = rootNode.ComputeMinterms();

            _matcher = minterms.Length > 64 ?
                       SymbolicRegexMatcher <BitVector> .Create(regexTree.CaptureCount, regexTree.FindOptimizations, bddBuilder, rootNode, new BitVectorSolver(minterms, charSetSolver), matchTimeout) :
                       SymbolicRegexMatcher <ulong> .Create(regexTree.CaptureCount, regexTree.FindOptimizations, bddBuilder, rootNode, new UInt64Solver(minterms, charSetSolver), matchTimeout);
        }
            static string FormatInfo(SymbolicRegexMatcher <TSet> matcher, int transitionCount)
            {
                StringBuilder sb = new();

                sb.Append($"States = {matcher._stateCache.Count}&#13;");
                sb.Append($"Transitions = {transitionCount}&#13;");
                sb.Append($"Min Terms ({matcher.Solver.GetMinterms()!.Length}) = ").AppendJoin(',',
                                                                                               DescribeLabels(matcher.Solver.GetMinterms() !, matcher._builder));
                return(sb.ToString());
            }
Example #4
0
            public DfaMatchingState <TSetType> TakeTransition(
                SymbolicRegexMatcher <TSetType> matcher, DfaMatchingState <TSetType> currentState, int mintermId, TSetType minterm)
            {
                SymbolicRegexBuilder <TSetType> builder = matcher._builder;

                Debug.Assert(builder._delta is not null);

                int offset = (currentState.Id << builder._mintermsCount) | mintermId;

                return(Volatile.Read(ref builder._delta[offset]) ?? matcher.CreateNewTransition(currentState, minterm, offset));
            }
Example #5
0
        /// <summary>Initializes the factory.</summary>
        public SymbolicRegexRunnerFactory(RegexCode code, RegexOptions options, TimeSpan matchTimeout, CultureInfo culture)
        {
            // RightToLeft and ECMAScript are currently not supported in conjunction with NonBacktracking.
            if ((options & (RegexOptions.RightToLeft | RegexOptions.ECMAScript)) != 0)
            {
                throw new NotSupportedException(
                          SR.Format(SR.NotSupported_NonBacktrackingConflictingOption,
                                    (options & RegexOptions.RightToLeft) != 0 ? nameof(RegexOptions.RightToLeft) : nameof(RegexOptions.ECMAScript)));
            }

            var converter = new RegexNodeToSymbolicConverter(s_unicode, culture);
            var solver    = (CharSetSolver)s_unicode._solver;
            SymbolicRegexNode <BDD> root = converter.Convert(code.Tree.Root, topLevel: true);

            _minRequiredLength = code.Tree.MinRequiredLength;

            BDD[] minterms = root.ComputeMinterms();
            if (minterms.Length > 64)
            {
                // Use BV to represent a predicate
                var algBV     = new BVAlgebra(solver, minterms);
                var builderBV = new SymbolicRegexBuilder <BV>(algBV);

                // The default constructor sets the following predicates to False; this update happens after the fact.
                // It depends on whether anchors where used in the regex whether the predicates are actually different from False.
                builderBV._wordLetterPredicateForAnchors = algBV.ConvertFromCharSet(solver, converter._builder._wordLetterPredicateForAnchors);
                builderBV._newLinePredicate = algBV.ConvertFromCharSet(solver, converter._builder._newLinePredicate);

                //Convert the BDD based AST to BV based AST
                SymbolicRegexNode <BV> rootBV = converter._builder.Transform(root, builderBV, bdd => builderBV._solver.ConvertFromCharSet(solver, bdd));
                _matcher = new SymbolicRegexMatcher <BV>(rootBV, solver, minterms, matchTimeout, culture);
            }
            else
            {
                // Use ulong to represent a predicate
                var alg64     = new BV64Algebra(solver, minterms);
                var builder64 = new SymbolicRegexBuilder <ulong>(alg64)
                {
                    // The default constructor sets the following predicates to False, this update happens after the fact
                    // It depends on whether anchors where used in the regex whether the predicates are actually different from False
                    _wordLetterPredicateForAnchors = alg64.ConvertFromCharSet(solver, converter._builder._wordLetterPredicateForAnchors),
                    _newLinePredicate = alg64.ConvertFromCharSet(solver, converter._builder._newLinePredicate)
                };

                // Convert the BDD-based AST to ulong-based AST
                SymbolicRegexNode <ulong> root64 = converter._builder.Transform(root, builder64, bdd => builder64._solver.ConvertFromCharSet(solver, bdd));
                _matcher = new SymbolicRegexMatcher <ulong>(root64, solver, minterms, matchTimeout, culture);
            }
        }
 static IEnumerable <MatchingState <TSet> > GetInitialStates(SymbolicRegexMatcher <TSet> matcher)
 {
     foreach (MatchingState <TSet> state in matcher._dotstarredInitialStates)
     {
         yield return(state);
     }
     foreach (MatchingState <TSet> state in matcher._initialStates)
     {
         yield return(state);
     }
     foreach (MatchingState <TSet> state in matcher._reverseInitialStates)
     {
         yield return(state);
     }
 }
Example #7
0
        /// <summary>Initializes the factory.</summary>
        public SymbolicRegexRunnerFactory(RegexTree regexTree, RegexOptions options, TimeSpan matchTimeout, CultureInfo culture)
        {
            Debug.Assert((options & (RegexOptions.RightToLeft | RegexOptions.ECMAScript)) == 0);

            var bddBuilder = new SymbolicRegexBuilder <BDD>(CharSetSolver.Instance);
            var converter  = new RegexNodeConverter(bddBuilder, culture, regexTree.CaptureNumberSparseMapping);

            SymbolicRegexNode <BDD> rootNode = converter.ConvertToSymbolicRegexNode(regexTree.Root, tryCreateFixedLengthMarker: true);

            BDD[] minterms = rootNode.ComputeMinterms();

            _matcher = minterms.Length > 64 ?
                       SymbolicRegexMatcher <BitVector> .Create(regexTree.CaptureCount, regexTree.FindOptimizations, bddBuilder, rootNode, new BitVectorAlgebra(minterms), matchTimeout) :
                       SymbolicRegexMatcher <ulong> .Create(regexTree.CaptureCount, regexTree.FindOptimizations, bddBuilder, rootNode, new UInt64Algebra(minterms), matchTimeout);
        }
Example #8
0
        /// <summary>Initializes the factory.</summary>
        public SymbolicRegexRunnerFactory(RegexTree regexTree, RegexOptions options, TimeSpan matchTimeout, CultureInfo culture)
        {
            // RightToLeft and ECMAScript are currently not supported in conjunction with NonBacktracking.
            if ((options & (RegexOptions.RightToLeft | RegexOptions.ECMAScript)) != 0)
            {
                throw new NotSupportedException(
                          SR.Format(SR.NotSupported_NonBacktrackingConflictingOption,
                                    (options & RegexOptions.RightToLeft) != 0 ? nameof(RegexOptions.RightToLeft) : nameof(RegexOptions.ECMAScript)));
            }

            var                     converter = new RegexNodeConverter(culture, regexTree.CaptureNumberSparseMapping);
            CharSetSolver           solver    = CharSetSolver.Instance;
            SymbolicRegexNode <BDD> root      = converter.ConvertToSymbolicRegexNode(regexTree.Root, tryCreateFixedLengthMarker: true);

            BDD[] minterms = root.ComputeMinterms();
            if (minterms.Length > 64)
            {
                // Use BitVector to represent a predicate
                var algebra = new BitVectorAlgebra(solver, minterms);
                var builder = new SymbolicRegexBuilder <BitVector>(algebra)
                {
                    // The default constructor sets the following predicates to False; this update happens after the fact.
                    // It depends on whether anchors where used in the regex whether the predicates are actually different from False.
                    _wordLetterPredicateForAnchors = algebra.ConvertFromCharSet(solver, converter._builder._wordLetterPredicateForAnchors),
                    _newLinePredicate = algebra.ConvertFromCharSet(solver, converter._builder._newLinePredicate)
                };

                // Convert the BDD-based AST to BitVector-based AST
                SymbolicRegexNode <BitVector> rootNode = converter._builder.Transform(root, builder, bdd => builder._solver.ConvertFromCharSet(solver, bdd));
                _matcher = new SymbolicRegexMatcher <BitVector>(rootNode, regexTree, minterms, matchTimeout);
            }
            else
            {
                // Use ulong to represent a predicate
                var algebra = new BitVector64Algebra(solver, minterms);
                var builder = new SymbolicRegexBuilder <ulong>(algebra)
                {
                    // The default constructor sets the following predicates to False, this update happens after the fact
                    // It depends on whether anchors where used in the regex whether the predicates are actually different from False
                    _wordLetterPredicateForAnchors = algebra.ConvertFromCharSet(solver, converter._builder._wordLetterPredicateForAnchors),
                    _newLinePredicate = algebra.ConvertFromCharSet(solver, converter._builder._newLinePredicate)
                };

                // Convert the BDD-based AST to ulong-based AST
                SymbolicRegexNode <ulong> rootNode = converter._builder.Transform(root, builder, bdd => builder._solver.ConvertFromCharSet(solver, bdd));
                _matcher = new SymbolicRegexMatcher <ulong>(rootNode, regexTree, minterms, matchTimeout);
            }
        }
Example #9
0
        /// <summary>Initializes the factory.</summary>
        public SymbolicRegexRunnerFactory(RegexTree regexTree, RegexOptions options, TimeSpan matchTimeout)
        {
            Debug.Assert((options & (RegexOptions.RightToLeft | RegexOptions.ECMAScript)) == 0);

            var charSetSolver = new CharSetSolver();
            var bddBuilder    = new SymbolicRegexBuilder <BDD>(charSetSolver, charSetSolver);
            var converter     = new RegexNodeConverter(bddBuilder, regexTree.CaptureNumberSparseMapping);

            SymbolicRegexNode <BDD> rootNode = converter.ConvertToSymbolicRegexNode(regexTree.Root);

            BDD[] minterms = rootNode.ComputeMinterms();

            _matcher = minterms.Length > 64 ?
                       SymbolicRegexMatcher <BitVector> .Create(regexTree.CaptureCount, regexTree.FindOptimizations, bddBuilder, rootNode, new BitVectorSolver(minterms, charSetSolver), matchTimeout) :
                       SymbolicRegexMatcher <ulong> .Create(regexTree.CaptureCount, regexTree.FindOptimizations, bddBuilder, rootNode, new UInt64Solver(minterms, charSetSolver), matchTimeout);
        }
Example #10
0
        private SymbolicRegexRunner(RegexCode code, TimeSpan matchTimeout, CultureInfo culture)
        {
            var converter = new RegexNodeToSymbolicConverter(s_unicode, culture);
            var solver    = (CharSetSolver)s_unicode._solver;
            SymbolicRegexNode <BDD> root = converter.Convert(code.Tree.Root, topLevel: true);

            _minRequiredLength = code.Tree.MinRequiredLength;

            BDD[] minterms = root.ComputeMinterms();
            if (minterms.Length > 64)
            {
                // Use BV to represent a predicate
                var algBV     = new BVAlgebra(solver, minterms);
                var builderBV = new SymbolicRegexBuilder <BV>(algBV);

                // The default constructor sets the following predicates to False; this update happens after the fact.
                // It depends on whether anchors where used in the regex whether the predicates are actually different from False.
                builderBV._wordLetterPredicateForAnchors = algBV.ConvertFromCharSet(solver, converter._builder._wordLetterPredicateForAnchors);
                builderBV._newLinePredicate = algBV.ConvertFromCharSet(solver, converter._builder._newLinePredicate);

                //Convert the BDD based AST to BV based AST
                SymbolicRegexNode <BV> rootBV = converter._builder.Transform(root, builderBV, bdd => builderBV._solver.ConvertFromCharSet(solver, bdd));
                _matcher = new SymbolicRegexMatcher <BV>(rootBV, solver, minterms, matchTimeout, culture);
            }
            else
            {
                // Use ulong to represent a predicate
                var alg64     = new BV64Algebra(solver, minterms);
                var builder64 = new SymbolicRegexBuilder <ulong>(alg64)
                {
                    // The default constructor sets the following predicates to False, this update happens after the fact
                    // It depends on whether anchors where used in the regex whether the predicates are actually different from False
                    _wordLetterPredicateForAnchors = alg64.ConvertFromCharSet(solver, converter._builder._wordLetterPredicateForAnchors),
                    _newLinePredicate = alg64.ConvertFromCharSet(solver, converter._builder._newLinePredicate)
                };

                // Convert the BDD-based AST to ulong-based AST
                SymbolicRegexNode <ulong> root64 = converter._builder.Transform(root, builder64, bdd => builder64._solver.ConvertFromCharSet(solver, bdd));
                _matcher = new SymbolicRegexMatcher <ulong>(root64, solver, minterms, matchTimeout, culture);
            }
        }
Example #11
0
        /// <summary>Write the DFA or NFA in DGML format into the TextWriter.</summary>
        /// <param name="matcher">The <see cref="SymbolicRegexMatcher"/> for the regular expression.</param>
        /// <param name="writer">Writer to which the DGML is written.</param>
        /// <param name="nfa">True to create an NFA instead of a DFA.</param>
        /// <param name="addDotStar">True to prepend .*? onto the pattern (outside of the implicit root capture).</param>
        /// <param name="reverse">If true, then unwind the regex backwards (and <paramref name="addDotStar"/> is ignored).</param>
        /// <param name="maxStates">The approximate maximum number of states to include; less than or equal to 0 for no maximum.</param>
        /// <param name="maxLabelLength">maximum length of labels in nodes anything over that length is indicated with .. </param>
        public static void Write(
            TextWriter writer, SymbolicRegexMatcher <TSet> matcher,
            bool nfa = false, bool addDotStar = true, bool reverse = false, int maxStates = -1, int maxLabelLength = -1)
        {
            var charSetSolver         = new CharSetSolver();
            var explorer              = new DfaExplorer(matcher, nfa, addDotStar, reverse, maxStates);
            var nonEpsilonTransitions = new Dictionary <(int SourceState, int TargetState), List <(SymbolicRegexNode <TSet>?, TSet)> >();
            var epsilonTransitions    = new List <Transition>();

            foreach (Transition transition in explorer.GetTransitions())
            {
                if (transition.IsEpsilon)
                {
                    epsilonTransitions.Add(transition);
                }
                else
                {
                    (int SourceState, int TargetState)p = (transition.SourceState, transition.TargetState);
                    if (!nonEpsilonTransitions.TryGetValue(p, out List <(SymbolicRegexNode <TSet>?, TSet)>?rules))
                    {
                        nonEpsilonTransitions[p] = rules = new List <(SymbolicRegexNode <TSet>?, TSet)>();
                    }

                    rules.Add(transition.Label);
                }
            }

            writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            writer.WriteLine("<DirectedGraph xmlns=\"http://schemas.microsoft.com/vs/2009/dgml\" ZoomLevel=\"1.5\" GraphDirection=\"TopToBottom\" >");
            writer.WriteLine("    <Nodes>");
            writer.WriteLine("        <Node Id=\"dfa\" Label=\" \" Group=\"Collapsed\" Category=\"DFA\" DFAInfo=\"{0}\" />", GetDFAInfo(explorer, charSetSolver));
            writer.WriteLine("        <Node Id=\"dfainfo\" Category=\"DFAInfo\" Label=\"{0}\"/>", GetDFAInfo(explorer, charSetSolver));
            foreach (int state in explorer.GetStates())
            {
                writer.WriteLine("        <Node Id=\"{0}\" Label=\"{0}\" Category=\"State\" Group=\"Collapsed\" StateInfo=\"{1}\">", state, explorer.DescribeState(state));
                if (state == explorer.InitialState)
                {
                    writer.WriteLine("            <Category Ref=\"InitialState\" />");
                }
                if (explorer.IsFinalState(state))
                {
                    writer.WriteLine("            <Category Ref=\"FinalState\" />");
                }
                writer.WriteLine("        </Node>");
                writer.WriteLine("        <Node Id=\"{0}info\" Label=\"{1}\" Category=\"StateInfo\"/>", state, explorer.DescribeState(state));
            }
            writer.WriteLine("    </Nodes>");
            writer.WriteLine("    <Links>");
            writer.WriteLine("        <Link Source=\"dfa\" Target=\"{0}\" Label=\"\" Category=\"StartTransition\" />", explorer.InitialState);
            writer.WriteLine("        <Link Source=\"dfa\" Target=\"dfainfo\" Label=\"\" Category=\"Contains\" />");

            foreach (Transition transition in epsilonTransitions)
            {
                writer.WriteLine("        <Link Source=\"{0}\" Target=\"{1}\" Category=\"EpsilonTransition\" />", transition.SourceState, transition.TargetState);
            }

            foreach (KeyValuePair <(int, int), List <(SymbolicRegexNode <TSet>?, TSet)> > transition in nonEpsilonTransitions)
            {
                string label = string.Join($",{Environment.NewLine} ", DescribeLabels(explorer, transition.Value, charSetSolver));
                string info  = "";
                if (label.Length > (uint)maxLabelLength)
                {
                    info  = $"FullLabel = \"{label}\" ";
                    label = string.Concat(label.AsSpan(0, maxLabelLength), "..");
                }

                writer.WriteLine($"        <Link Source=\"{transition.Key.Item1}\" Target=\"{transition.Key.Item2}\" Label=\"{label}\" Category=\"NonEpsilonTransition\" {info}/>");
            }

            foreach (int state in explorer.GetStates())
            {
                writer.WriteLine("        <Link Source=\"{0}\" Target=\"{0}info\" Category=\"Contains\" />", state);
            }

            writer.WriteLine("    </Links>");
            writer.WriteLine("    <Categories>");
            writer.WriteLine("        <Category Id=\"DFA\" Label=\"DFA\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"EpsilonTransition\" Label=\"Epsilon transition\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"StartTransition\" Label=\"Initial transition\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"FinalLabel\" Label=\"Final transition\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"FinalState\" Label=\"Final\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"SinkState\" Label=\"Sink state\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"EpsilonState\" Label=\"Epsilon state\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"InitialState\" Label=\"Initial\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"NonEpsilonTransition\" Label=\"Nonepsilon transition\" IsTag=\"True\" />");
            writer.WriteLine("        <Category Id=\"State\" Label=\"State\" IsTag=\"True\" />");
            writer.WriteLine("    </Categories>");
            writer.WriteLine("    <Styles>");
            writer.WriteLine("        <Style TargetType=\"Node\" GroupLabel=\"InitialState\" ValueLabel=\"True\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('InitialState')\" />");
            writer.WriteLine("            <Setter Property=\"Background\" Value=\"lightgray\" />");
            writer.WriteLine("            <Setter Property=\"MinWidth\" Value=\"0\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Node\" GroupLabel=\"FinalState\" ValueLabel=\"True\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('FinalState')\" />");
            writer.WriteLine("            <Setter Property=\"Background\" Value=\"lightgreen\" />");
            writer.WriteLine("            <Setter Property=\"StrokeThickness\" Value=\"4\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Node\" GroupLabel=\"State\" ValueLabel=\"True\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('State')\" />");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"black\" />");
            writer.WriteLine("            <Setter Property=\"Background\" Value=\"white\" />");
            writer.WriteLine("            <Setter Property=\"MinWidth\" Value=\"0\" />");
            writer.WriteLine("            <Setter Property=\"FontSize\" Value=\"12\" />");
            writer.WriteLine("            <Setter Property=\"FontFamily\" Value=\"Arial\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Link\" GroupLabel=\"NonEpsilonTransition\" ValueLabel=\"True\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('NonEpsilonTransition')\" />");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"black\" />");
            writer.WriteLine("            <Setter Property=\"FontSize\" Value=\"18\" />");
            writer.WriteLine("            <Setter Property=\"FontFamily\" Value=\"Arial\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Link\" GroupLabel=\"StartTransition\" ValueLabel=\"True\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('StartTransition')\" />");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"black\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Link\" GroupLabel=\"EpsilonTransition\" ValueLabel=\"True\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('EpsilonTransition')\" />");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"black\" />");
            writer.WriteLine("            <Setter Property=\"StrokeDashArray\" Value=\"8 8\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Link\" GroupLabel=\"FinalLabel\" ValueLabel=\"False\">");
            writer.WriteLine("            <Condition Expression=\"HasCategory('FinalLabel')\" />");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"black\" />");
            writer.WriteLine("            <Setter Property=\"StrokeDashArray\" Value=\"8 8\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Node\" GroupLabel=\"StateInfo\" ValueLabel=\"True\">");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"white\" />");
            writer.WriteLine("            <Setter Property=\"FontSize\" Value=\"18\" />");
            writer.WriteLine("            <Setter Property=\"FontFamily\" Value=\"Arial\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("        <Style TargetType=\"Node\" GroupLabel=\"DFAInfo\" ValueLabel=\"True\">");
            writer.WriteLine("            <Setter Property=\"Stroke\" Value=\"white\" />");
            writer.WriteLine("            <Setter Property=\"FontSize\" Value=\"18\" />");
            writer.WriteLine("            <Setter Property=\"FontFamily\" Value=\"Arial\" />");
            writer.WriteLine("        </Style>");
            writer.WriteLine("    </Styles>");
            writer.WriteLine("</DirectedGraph>");
        }
Example #12
0
 internal Runner(SymbolicRegexMatcher <TSet> matcher)
 {
     _matcher       = matcher;
     _perThreadData = matcher.CreatePerThreadData();
 }
            // This function gathers all transitions in the given builder and groups them by (source,destination) state ID
            static Dictionary <(int Source, int Target), (TSet Rule, List <int> NfaTargets)> GatherTransitions(SymbolicRegexMatcher <TSet> matcher)
            {
                Dictionary <(int Source, int Target), (TSet Rule, List <int> NfaTargets)> result = new();

                foreach (MatchingState <TSet> source in matcher._stateCache.Values)
                {
                    // Get the span of entries in delta that gives the transitions for the different minterms
                    Span <int>    deltas    = matcher.GetDeltasFor(source);
                    Span <int[]?> nfaDeltas = matcher.GetNfaDeltasFor(source);
                    Debug.Assert(deltas.Length == matcher._minterms.Length);
                    for (int i = 0; i < deltas.Length; ++i)
                    {
                        // negative entries are transitions not explored yet, so skip them
                        int targetId = deltas[i];
                        if (targetId >= 0)
                        {
                            // Get or create the data for this (source,destination) state ID pair
                            (int Source, int Target)key = (source.Id, targetId);
                            if (!result.TryGetValue(key, out (TSet Rule, List <int> NfaTargets)entry))
                            {
                                entry = (matcher.Solver.Empty, new List <int>());
                            }
                            // If this state has an NFA transition for the same minterm, then associate
                            // those with the transition.
                            if (nfaDeltas.Length > 0 && nfaDeltas[i] is int[] nfaTargets)
                            {
                                foreach (int nfaTarget in nfaTargets)
                                {
                                    entry.NfaTargets.Add(matcher._nfaCoreIdArray[nfaTarget]);
                                }
                            }
                            // Expand the rule for this minterm
                            result[key] = (matcher.Solver.Or(entry.Rule, matcher._minterms[i]), entry.NfaTargets);
                        }
                    }
                }
                return(result);
            }
Example #14
0
#pragma warning disable CA2252 // This API requires opting into preview features
            /// <summary>Find the next state given the current state and next character.</summary>
            static abstract DfaMatchingState <TSetType> TakeTransition(SymbolicRegexMatcher <TSetType> matcher, DfaMatchingState <TSetType> currentState, int mintermId, TSetType minterm);
 internal Runner(SymbolicRegexMatcher <TSetType> matcher) => _matcher = matcher;
Example #16
0
 internal Runner(SymbolicRegexMatcher matcher, int minRequiredLength)
 {
     _matcher           = matcher;
     _minRequiredLength = minRequiredLength;
 }