private InternalResult <IEnumerable <T> > Rest(Parser <TToken, T> parser, ref ParseState <TToken> state, List <T> ts, bool consumedInput) { state.BeginExpectedTran(); var result = parser.Parse(ref state); while (result.Success) { state.EndExpectedTran(false); if (!result.ConsumedInput) { throw new InvalidOperationException("Many() used with a parser which consumed no input"); } consumedInput = true; ts.Add(result.Value); state.BeginExpectedTran(); result = parser.Parse(ref state); } state.EndExpectedTran(result.ConsumedInput); if (result.ConsumedInput) // the most recent parser failed after consuming input { // state.Error set by parser return(InternalResult.Failure <IEnumerable <T> >(true)); } return(InternalResult.Success <IEnumerable <T> >(ts, consumedInput)); }
// see comment about expecteds in ParseState.Error.cs internal sealed override InternalResult <T> Parse(ref ParseState <TToken> state) { var firstTime = true; var err = new InternalError <TToken>( Maybe.Nothing <TToken>(), false, state.Location, "OneOf had no arguments" ); state.BeginExpectedTran(); foreach (var p in _parsers) { state.BeginExpectedTran(); var thisResult = p.Parse(ref state); if (thisResult.Success) { // throw out all expecteds state.EndExpectedTran(false); state.EndExpectedTran(false); return(thisResult); } // we'll usually return the error from the first parser that didn't backtrack, // even if other parsers had a longer match. // There is some room for improvement here. if (thisResult.ConsumedInput) { // throw out all expecteds except this one var expected = state.ExpectedTranState(); state.EndExpectedTran(false); state.EndExpectedTran(false); state.AddExpected(expected.AsSpan()); expected.Dispose(clearArray: true); return(thisResult); } state.EndExpectedTran(true); // choose the longest match, preferring the left-most error in a tie, // except the first time (avoid returning "OneOf had no arguments"). if (firstTime || state.Error.ErrorLocation > err.ErrorLocation) { err = state.Error; } firstTime = false; } state.Error = err; state.EndExpectedTran(true); return(InternalResult.Failure <T>(false)); }
internal sealed override InternalResult <T> Parse(ref ParseState <TToken> state) { state.BeginExpectedTran(); var result = _parser.Parse(ref state); state.EndExpectedTran(!result.Success); if (!result.Success) { return(result); } var val = result.Value; if (!_predicate(val)) { state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), false, state.Location, _message(val) ); state.AddExpected(_expected); return(InternalResult.Failure <T>(result.ConsumedInput)); } return(result); }
internal sealed override InternalResult <Unit> Parse(ref ParseState <TToken> state) { var startingPosition = state.SourcePos; var token = state.HasCurrent ? Maybe.Just(state.Current) : Maybe.Nothing <TToken>(); state.BeginExpectedTran(); var result = _parser.Parse(ref state); state.EndExpectedTran(false); if (result.Success) { state.Error = new InternalError <TToken>( token, false, startingPosition, null ); return(InternalResult.Failure <Unit>(result.ConsumedInput)); } return(InternalResult.Success( Unit.Value, result.ConsumedInput )); }
internal sealed override InternalResult <Unit> Parse(ref ParseState <TToken> state) { var startingLocation = state.Location; var token = state.HasCurrent ? Maybe.Just(state.Current) : Maybe.Nothing <TToken>(); state.PushBookmark(); // make sure we don't throw out the buffer, we may need it to compute a SourcePos state.BeginExpectedTran(); var result = _parser.Parse(ref state); state.EndExpectedTran(false); state.PopBookmark(); if (result.Success) { state.Error = new InternalError <TToken>( token, false, startingLocation, null ); return(InternalResult.Failure <Unit>(result.ConsumedInput)); } return(InternalResult.Success( Unit.Value, result.ConsumedInput )); }
internal override InternalResult <IEnumerable <T> > Parse(ref ParseState <TToken> state) { var result = _parser.Parse(ref state); if (!result.Success) { // state.Error set by _parser return(InternalResult.Failure <IEnumerable <T> >(result.ConsumedInput)); } var ts = new List <T> { result.Value }; var consumedInput = result.ConsumedInput; while (true) { state.BeginExpectedTran(); var sepResult = _separator.Parse(ref state); state.EndExpectedTran(!sepResult.Success && sepResult.ConsumedInput); consumedInput = consumedInput || sepResult.ConsumedInput; if (!sepResult.Success) { if (sepResult.ConsumedInput) { // state.Error set by _separator return(InternalResult.Failure <IEnumerable <T> >(consumedInput)); } return(InternalResult.Success <IEnumerable <T> >(ts, consumedInput)); } state.BeginExpectedTran(); var itemResult = _parser.Parse(ref state); state.EndExpectedTran(!itemResult.Success && itemResult.ConsumedInput); consumedInput = consumedInput || itemResult.ConsumedInput; if (!itemResult.Success) { if (itemResult.ConsumedInput) { // state.Error set by _parser return(InternalResult.Failure <IEnumerable <T> >(consumedInput)); } return(InternalResult.Success <IEnumerable <T> >(ts, consumedInput)); } ts.Add(itemResult.Value); } }
public override InternalResult <U> Parse(ref ParseState <TToken> state) { var result1 = _parser.Parse(ref state); if (!result1.Success) { // state.Error set by _parser return(InternalResult.Failure <U>(result1.ConsumedInput)); } var chainer = _factory(); chainer.Apply(result1.Value); var consumedInput = result1.ConsumedInput; state.BeginExpectedTran(); var result = _parser.Parse(ref state); while (result.Success) { state.EndExpectedTran(false); if (!result.ConsumedInput) { chainer.OnError(); throw new InvalidOperationException("Many() used with a parser which consumed no input"); } consumedInput = true; chainer.Apply(result.Value); state.BeginExpectedTran(); result = _parser.Parse(ref state); } state.EndExpectedTran(result.ConsumedInput); if (result.ConsumedInput) // the most recent parser failed after consuming input { // state.Error set by _parser chainer.OnError(); return(InternalResult.Failure <U>(true)); } var z = chainer.GetResult(); return(InternalResult.Success <U>(z, consumedInput)); }
internal override InternalResult <T> Parse(ref ParseState <TToken> state) { state.BeginExpectedTran(); var result = _parser.Parse(ref state); state.EndExpectedTran(false); if (!result.Success) { state.AddExpected(_expected); } return(result); }
internal override InternalResult <U> Parse(ref ParseState <TToken> state) { var result1 = _parser.Parse(ref state); if (!result1.Success) { // state.Error set by _parser return(InternalResult.Failure <U>(result1.ConsumedInput)); } var z = _func(_seed(), result1.Value); var consumedInput = result1.ConsumedInput; state.BeginExpectedTran(); var result = _parser.Parse(ref state); while (result.Success) { state.EndExpectedTran(false); if (!result.ConsumedInput) { _onFail?.Invoke(z); throw new InvalidOperationException("Many() used with a parser which consumed no input"); } consumedInput = true; z = _func(z, result.Value); state.BeginExpectedTran(); result = _parser.Parse(ref state); } state.EndExpectedTran(result.ConsumedInput); if (result.ConsumedInput) // the most recent parser failed after consuming input { // state.Error set by _parser _onFail?.Invoke(z); return(InternalResult.Failure <U>(true)); } return(InternalResult.Success <U>(z, consumedInput)); }
// see comment about expecteds in ParseState.Error.cs internal override InternalResult <T> Parse(ref ParseState <TToken> state) { state.BeginExpectedTran(); var result = _parser.Parse(ref state); if (result.Success) { state.EndExpectedTran(false); return(result); } var parserExpecteds = state.ExpectedTranState(); state.EndExpectedTran(false); var recoverParser = _errorHandler(state.BuildError(parserExpecteds.AsEnumerable())); parserExpecteds.Dispose(clearArray: true); return(recoverParser.Parse(ref state)); }
// see comment about expecteds in ParseState.Error.cs internal override InternalResult <IEnumerable <T> > Parse(ref ParseState <TToken> state) { var ts = _keepResults ? new List <T>() : null; var firstItemResult = _parser.Parse(ref state); if (!firstItemResult.Success) { // state.Error set by _parser return(InternalResult.Failure <IEnumerable <T> >(firstItemResult.ConsumedInput)); } if (!firstItemResult.ConsumedInput) { throw new InvalidOperationException("Until() used with a parser which consumed no input"); } ts?.Add(firstItemResult.Value); while (true) { state.BeginExpectedTran(); var terminatorResult = _terminator.Parse(ref state); if (terminatorResult.Success) { state.EndExpectedTran(false); return(InternalResult.Success <IEnumerable <T> >(ts, true)); } if (terminatorResult.ConsumedInput) { // state.Error set by _terminator state.EndExpectedTran(true); return(InternalResult.Failure <IEnumerable <T> >(true)); } state.BeginExpectedTran(); var itemResult = _parser.Parse(ref state); if (!itemResult.Success) { if (!itemResult.ConsumedInput) { // get the expected from both _terminator and _parser state.EndExpectedTran(true); state.EndExpectedTran(true); } else { // throw out the _terminator expecteds and keep only _parser var itemExpected = state.ExpectedTranState(); state.EndExpectedTran(false); state.EndExpectedTran(false); state.AddExpected(itemExpected.AsSpan()); itemExpected.Dispose(); } return(InternalResult.Failure <IEnumerable <T> >(true)); } // throw out both sets of expecteds state.EndExpectedTran(false); state.EndExpectedTran(false); if (!itemResult.ConsumedInput) { throw new InvalidOperationException("Until() used with a parser which consumed no input"); } ts?.Add(itemResult.Value); } }