public IResult <TOutput> Parse(IParseState <TInput> state)
        {
            Assert.ArgumentNotNull(state, nameof(state));
            var startCheckpoint = state.Input.Checkpoint();

            try
            {
                var seqState = new State <TInput>(state);
                var result   = Function(seqState);
                return(state.Success(this, result, seqState.Consumed, startCheckpoint.Location));
            }
            catch (ParseFailedException spe)
            {
                // This exception is part of normal flow-control for this parser
                // Other exceptions bubble up like normal.
                startCheckpoint.Rewind();
                if (spe.Result != null)
                {
                    var result = spe.Result;
                    state.Log(this, $"Parse failed during sequential callback: {result}\n\n{spe.StackTrace}");
                    return(state.Fail(this, $"Error during parsing: {result.Parser} {result.ErrorMessage} at {result.Location}"));
                }

                state.Log(this, $"Failure triggered during sequential callback: {spe.Message}");
                return(state.Fail(this, $"Failure during parsing: {spe.Message}"));
            }
            catch (Exception e)
            {
                startCheckpoint.Rewind();
                state.Log(this, $"Parse failed during sequential callback: {e.Message}");
                throw;
            }
        }
Esempio n. 2
0
    public IResult <IReadOnlyList <TOutput> > Parse(IParseState <TInput> state)
    {
        Assert.ArgumentNotNull(state, nameof(state));

        var startCheckpoint = state.Input.Checkpoint();
        var items           = new List <TOutput>();

        int consumed = 0;

        while (Maximum == null || items.Count < Maximum)
        {
            var result = _parser.Parse(state);
            if (!result.Success)
            {
                break;
            }
            consumed += result.Consumed;
            items.Add(result.Value);
            if (items.Count >= Minimum && result.Consumed == 0)
            {
                break;
            }
        }

        if (Minimum > 0 && items.Count < Minimum)
        {
            startCheckpoint.Rewind();
            return(state.Fail(this, $"Expected at least {Minimum} items but only found {items.Count}", startCheckpoint.Location));
        }

        return(state.Success(this, items, consumed, startCheckpoint.Location));
    }
Esempio n. 3
0
 public IResult <TOutput> Parse(IParseState <TInput> state)
 {
     Assert.ArgumentNotNull(state, nameof(state));
     return(_quantifier switch
     {
         Quantifier.ExactlyOne => ParseExactlyOne(state),
         Quantifier.ZeroOrOne => ParseZeroOrOne(state),
         Quantifier.ZeroOrMore => ParseZeroOrMore(state),
         _ => state.Fail(this, $"Quantifier value {_quantifier} not supported"),
     });