internal bool IsNullableFor(uint nextCharKind) { Debug.Assert(CharKind.IsValidCharKind(nextCharKind)); uint context = CharKind.Context(PrevCharKind, nextCharKind); return(Node.IsNullableFor(context)); }
/// <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)); }