Пример #1
0
        internal bool IsNullableFor(uint nextCharKind)
        {
            Debug.Assert(CharKind.IsValidCharKind(nextCharKind));
            uint context = CharKind.Context(PrevCharKind, nextCharKind);

            return(Node.IsNullableFor(context));
        }
Пример #2
0
        /// <summary>Find a match.</summary>
        /// <param name="isMatch">Whether to return once we know there's a match without determining where exactly it matched.</param>
        /// <param name="input">The input span</param>
        /// <param name="startat">The position to start search in the input span.</param>
        /// <param name="end">The non-inclusive position to end the search in the input span.</param>
        public SymbolicMatch FindMatch(bool isMatch, ReadOnlySpan <char> input, int startat, int end)
        {
            int timeoutOccursAt = 0;

            if (_checkTimeout)
            {
                // Using Environment.TickCount for efficiency instead of Stopwatch -- as in the non-DFA case.
                timeoutOccursAt = Environment.TickCount + (int)(_timeout + 0.5);
            }

            if (startat == end)
            {
                // Covers the special-case of an empty match at the end of the input.
                uint prevKind = GetCharKind(input, startat - 1);
                uint nextKind = GetCharKind(input, startat);

                bool emptyMatchExists = _pattern.IsNullableFor(CharKind.Context(prevKind, nextKind));
                return(emptyMatchExists ?
                       new SymbolicMatch(startat, 0) :
                       SymbolicMatch.NoMatch);
            }

            // Find the first accepting state. Initial start position in the input is i == 0.
            int i = startat;

            // May return -1 as a legitimate value when the initial state is nullable and startat == 0.
            // Returns NoMatchExists when there is no match.
            i = FindFinalStatePosition(input, end, i, timeoutOccursAt, out int i_q0_A1, out int watchdog);

            if (i == NoMatchExists)
            {
                return(SymbolicMatch.NoMatch);
            }

            if (isMatch)
            {
                // this means success -- the original call was IsMatch
                return(SymbolicMatch.QuickMatch);
            }

            int i_start;
            int i_end;

            if (watchdog >= 0)
            {
                i_start = i - watchdog + 1;
                i_end   = i;
            }
            else
            {
                Debug.Assert(i >= startat - 1);
                i_start = i < startat ?
                          startat :
                          FindStartPosition(input, i, i_q0_A1); // Walk in reverse to locate the start position of the match
                i_end = FindEndPosition(input, end, i_start);
            }

            return(new SymbolicMatch(i_start, i_end + 1 - i_start));
        }