예제 #1
0
    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;
            }
        }
    }
예제 #2
0
    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();
    }
예제 #3
0
    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");
    }