private static void TestRange(RegexContext context, SequenceBuffer <char> buffer) { var backtrackState = new BacktrackState(true, context.CurrentState); int j = 0; while (true) { if (buffer.IsPastEnd(context.Index)) { backtrackState.AddZeroConsumed(); context.Push(backtrackState); context.MoveToNextState(); break; } var(matches, consumed) = MatchStateHere(context.CurrentState, buffer, context.Index); if (!matches || consumed == 0) { backtrackState.AddZeroConsumed(); context.Push(backtrackState); context.MoveToNextState(); break; } backtrackState.AddConsumption(consumed); context.AdvanceIndex(consumed); j++; if (j >= context.CurrentState.Maximum) { context.MoveToNextState(); break; } } }
private static void TestZeroOrOne(RegexContext context, SequenceBuffer <char> buffer) { if (buffer.IsPastEnd(context.Index)) { context.Push(new BacktrackState(false, context.CurrentState, 0)); context.MoveToNextState(); return; } var(matches, consumed) = MatchStateHere(context.CurrentState, buffer, context.Index); context.Push(new BacktrackState(matches && consumed > 0, context.CurrentState, consumed)); context.AdvanceIndex(consumed); context.MoveToNextState(); }
private static (bool matches, int length) MatchStateHere(State state, SequenceBuffer <char> context, int i) { if (context.IsPastEnd(i)) { if (state.Type == StateType.EndOfInput) { return(true, 0); } return(false, 0); } if (state.Type == StateType.EndOfInput) { return(false, 0); } if (state.Type == StateType.MatchValue) { var match = state.ValuePredicate?.Invoke(context[i]) ?? false; return(match, match ? 1 : 0); } if (state.Type == StateType.Group) { return(Test(state.Group !, context.CopyFrom(i))); } if (state.Type == StateType.Alternation) { foreach (var substate in state.Alternations !) { var(matches, consumed) = Test(substate, context.CopyFrom(i)); if (matches) { return(true, consumed); } } return(false, 0); } throw new RegexException("Unsupported state type during match"); }