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)); }
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; } }
IResult IParser <TInput> .Parse(IParseState <TInput> state) => state.Success(this, Value !, 0, Location !);
public IResult <TMiddle> Parse(IParseState <TInput> state) => state.Success(this, Value !, 0, Location !);