internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out TToken result) { if (!state.HasCurrent) { state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), true, state.Location, null ); result = default; return(false); } var token = state.Current; if (!_predicate(token)) { state.Error = new InternalError <TToken>( Maybe.Just(token), false, state.Location, null ); result = default; return(false); } state.Advance(); result = token; return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out Unit result) { 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 var childExpecteds = new ExpectedCollector <TToken>(true); var success = _parser.TryParse(ref state, ref childExpecteds, out var result1); childExpecteds.Dispose(); state.PopBookmark(); if (success) { state.Error = new InternalError <TToken>( token, false, startingLocation, null ); result = default; return(false); } result = Unit.Value; return(true); }
private bool Rest(Parser <TToken, T> parser, ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, List <T> ts) { var lastStartingLoc = state.Location; var childExpecteds = new ExpectedCollector <TToken>(); var success = parser.TryParse(ref state, ref childExpecteds, out var result); while (success) { var endingLoc = state.Location; childExpecteds.Clear(); if (endingLoc <= lastStartingLoc) { childExpecteds.Dispose(); throw new InvalidOperationException("Many() used with a parser which consumed no input"); } ts.Add(result); lastStartingLoc = endingLoc; success = parser.TryParse(ref state, ref childExpecteds, out result); } var lastParserConsumedInput = state.Location > lastStartingLoc; expecteds.AddIf(ref childExpecteds, lastParserConsumedInput); childExpecteds.Dispose(); // we fail if the most recent parser failed after consuming input. // it sets state.Error for us return(!lastParserConsumedInput); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out R result) { var success1 = _p1.TryParse(ref state, ref expecteds, out var result1); if (!success1) { result = default; return(false); } var success2 = _p2.TryParse(ref state, ref expecteds, out var result2); if (!success2) { result = default; return(false); } var success3 = _p3.TryParse(ref state, ref expecteds, out var result3); if (!success3) { result = default; return(false); } var success4 = _p4.TryParse(ref state, ref expecteds, out var result4); if (!success4) { result = default; return(false); } var success5 = _p5.TryParse(ref state, ref expecteds, out var result5); if (!success5) { result = default; return(false); } var success6 = _p6.TryParse(ref state, ref expecteds, out var result6); if (!success6) { result = default; return(false); } result = _func( result1, result2, result3, result4, result5, result6 ); return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { var childExpecteds = new ExpectedCollector <TToken>(); var success = _parser.TryParse(ref state, ref childExpecteds, out result); expecteds.AddIf(ref childExpecteds, success); childExpecteds.Dispose(); if (!success) { return(false); } if (!_predicate(result)) { state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), false, state.Location, _message(result) ); expecteds.Add(_expected); result = default; return(false); } return(true); }
// see comment about expecteds in ParseState.Error.cs internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { var firstTime = true; var err = new InternalError <TToken>( Maybe.Nothing <TToken>(), false, state.Location, "OneOf had no arguments" ); var childExpecteds = new ExpectedCollector <TToken>(); // the expecteds for all loop iterations var grandchildExpecteds = new ExpectedCollector <TToken>(); // the expecteds for the current loop iteration foreach (var p in _parsers) { var thisStartLoc = state.Location; var success = p.TryParse(ref state, ref grandchildExpecteds, out result); if (success) { // throw out all expecteds grandchildExpecteds.Dispose(); childExpecteds.Dispose(); return(true); } // 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 (state.Location > thisStartLoc) { // throw out all expecteds except this one expecteds.Add(ref grandchildExpecteds); childExpecteds.Dispose(); grandchildExpecteds.Dispose(); result = default; return(false); } childExpecteds.Add(ref grandchildExpecteds); grandchildExpecteds.Clear(); // 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; expecteds.Add(ref childExpecteds); childExpecteds.Dispose(); grandchildExpecteds.Dispose(); result = default; return(false); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { var childExpecteds = new ExpectedCollector <TToken>(true); var success = _parser.TryParse(ref state, ref childExpecteds, out result); childExpecteds.Dispose(); if (!success) { expecteds.Add(_expected); } return(success); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), false, state.Location, _message ); expecteds.Add(_expected); result = default; return(false); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { state.PushBookmark(); var success = _parser.TryParse(ref state, ref expecteds, out result); if (success) { state.Rewind(); return(true); } state.PopBookmark(); return(success); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out U result) { var success1 = _parser.TryParse(ref state, ref expecteds, out var result1); if (!success1) { // state.Error set by _parser result = default; return(false); } var chainer = _factory(); chainer.Apply(result1); var lastStartLoc = state.Location; var childExpecteds = new ExpectedCollector <TToken>(); var success = _parser.TryParse(ref state, ref childExpecteds, out var childResult); while (success) { var endLoc = state.Location; childExpecteds.Clear(); if (endLoc <= lastStartLoc) { childExpecteds.Dispose(); chainer.OnError(); throw new InvalidOperationException("Many() used with a parser which consumed no input"); } chainer.Apply(childResult); lastStartLoc = endLoc; success = _parser.TryParse(ref state, ref childExpecteds, out childResult); } var lastParserConsumedInput = state.Location > lastStartLoc; expecteds.AddIf(ref childExpecteds, lastParserConsumedInput); childExpecteds.Dispose(); if (lastParserConsumedInput) // the most recent parser failed after consuming input { // state.Error set by _parser chainer.OnError(); result = default; return(false); } result = chainer.GetResult(); return(true); }
internal sealed override bool TryParse(ref ParseState <char> state, ref ExpectedCollector <char> expecteds, out string result) { var span = state.LookAhead(_value.Length); // span.Length <= _valueTokens.Length var errorPos = -1; for (var i = 0; i < span.Length; i++) { if (!char.ToLowerInvariant(span[i]).Equals(char.ToLowerInvariant(_value[i]))) { errorPos = i; break; } } if (errorPos != -1) { // strings didn't match state.Advance(errorPos); state.Error = new InternalError <char>( Maybe.Just(span[errorPos]), false, state.Location, null ); expecteds.Add(Expected); result = null; return(false); } if (span.Length < _value.Length) { // strings matched but reached EOF state.Advance(span.Length); state.Error = new InternalError <char>( Maybe.Nothing <char>(), true, state.Location, null ); expecteds.Add(Expected); result = null; return(false); } // OK state.Advance(_value.Length); result = span.ToString(); return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out TEnumerable result) { var span = state.LookAhead(_valueTokens.Length); // span.Length <= _valueTokens.Length var errorPos = -1; for (var i = 0; i < span.Length; i++) { if (!EqualityComparer <TToken> .Default.Equals(span[i], _valueTokens[i])) { errorPos = i; break; } } if (errorPos != -1) { // strings didn't match state.Advance(errorPos); state.Error = new InternalError <TToken>( Maybe.Just(span[errorPos]), false, state.Location, null ); expecteds.Add(new Expected <TToken>(_valueTokens)); result = default; return(false); } if (span.Length < _valueTokens.Length) { // strings matched but reached EOF state.Advance(span.Length); state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), true, state.Location, null ); expecteds.Add(new Expected <TToken>(_valueTokens)); result = default; return(false); } // OK state.Advance(_valueTokens.Length); result = _value; return(true); }
private static Result <TToken, T> DoParse <TToken, T>(Parser <TToken, T> parser, ref ParseState <TToken> state) { var startingLoc = state.Location; var expecteds = new ExpectedCollector <TToken>(); var success = parser.TryParse(ref state, ref expecteds, out var result); var result1 = success ? new Result <TToken, T>(state.Location > startingLoc, result) : new Result <TToken, T>(state.Location > startingLoc, state.BuildError(ref expecteds)); expecteds.Dispose(); state.Dispose(); // ensure we return the state's buffers to the buffer pool return(result1); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out R result) { var success1 = _p1.TryParse(ref state, ref expecteds, out var result1); if (!success1) { result = default; return(false); } result = _func( result1 ); return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { // start buffering the input state.PushBookmark(); var success = _parser.TryParse(ref state, ref expecteds, out result); if (!success) { // return to the start of the buffer and discard the bookmark state.Rewind(); return(false); } // discard the buffer state.PopBookmark(); return(true); }
// see comment about expecteds in ParseState.Error.cs internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) { var childExpecteds = new ExpectedCollector <TToken>(); var success = _parser.TryParse(ref state, ref childExpecteds, out result); if (success) { childExpecteds.Dispose(); return(true); } var recoverParser = _errorHandler(state.BuildError(ref childExpecteds)); childExpecteds.Dispose(); return(recoverParser.TryParse(ref state, ref expecteds, out result)); }
internal override bool TryParse(ref ParseState <char> state, ref ExpectedCollector <char> expecteds, out Unit result) { result = Unit.Value; var chunk = state.LookAhead(32); while (chunk.Length > 0) { for (var i = 0; i < chunk.Length; i++) { if (!char.IsWhiteSpace(chunk[i])) { state.Advance(i); return(true); } } state.Advance(chunk.Length); chunk = state.LookAhead(32); } return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out string result) { var builder = new InplaceStringBuilder(_count); for (var _ = 0; _ < _count; _++) { var success = _parser.TryParse(ref state, ref expecteds, out var result1); if (!success) { result = null; return(false); } builder.Append(result1); } result = builder.ToString(); return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out IEnumerable <T> result) { var ts = new T[_parsers.Length]; for (var i = 0; i < _parsers.Length; i++) { var p = _parsers[i]; var success = p.TryParse(ref state, ref expecteds, out ts[i]); if (!success) { result = null; return(false); } } result = ts; return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out IEnumerable <T> result) { var success = _parser.TryParse(ref state, ref expecteds, out var result1); if (!success) { // state.Error set by _parser result = null; return(false); } var list = new List <T> { result1 }; success = Rest(_remainderParser, ref state, ref expecteds, list); if (!success) { result = null; return(false); } result = list; return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out U result) { var start = state.Location; state.PushBookmark(); // don't discard input buffer var success = _parser.TryParse(ref state, ref expecteds, out var result1); if (!success) { state.PopBookmark(); result = default; return(false); } var delta = state.Location - start; result = _selector(state.LookBehind(delta), result1); state.PopBookmark(); return(true); }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out R result) { var success = _parser.TryParse(ref state, ref expecteds, out var childResult); if (!success) { // state.Error set by _parser result = default; return(false); } var nextParser = _func(childResult); var nextSuccess = nextParser.TryParse(ref state, ref expecteds, out var nextResult); if (!nextSuccess) { // state.Error set by nextParser result = default; return(false); } result = _result(childResult, nextResult); return(true); }
// see comment about expecteds in ParseState.Error.cs internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out IEnumerable <T>?result) { var ts = _keepResults ? new List <T>() : null; var firstItemStartLoc = state.Location; var firstItemSuccess = _parser.TryParse(ref state, ref expecteds, out var result1); if (!firstItemSuccess) { // state.Error set by _parser result = null; return(false); } if (state.Location <= firstItemStartLoc) { throw new InvalidOperationException("Until() used with a parser which consumed no input"); } ts?.Add(result1); var terminatorExpecteds = new ExpectedCollector <TToken>(); var itemExpecteds = new ExpectedCollector <TToken>(); while (true) { var terminatorStartLoc = state.Location; var terminatorSuccess = _terminator.TryParse(ref state, ref terminatorExpecteds, out var terminatorResult); if (terminatorSuccess) { terminatorExpecteds.Dispose(); itemExpecteds.Dispose(); result = ts; return(true); } if (state.Location > terminatorStartLoc) { // state.Error set by _terminator expecteds.Add(ref terminatorExpecteds); terminatorExpecteds.Dispose(); itemExpecteds.Dispose(); result = null; return(false); } var itemStartLoc = state.Location; var itemSuccess = _parser.TryParse(ref state, ref itemExpecteds, out var itemResult); var itemConsumedInput = state.Location > itemStartLoc; if (!itemSuccess) { if (!itemConsumedInput) { // get the expected from both _terminator and _parser expecteds.Add(ref terminatorExpecteds); expecteds.Add(ref itemExpecteds); } else { // throw out the _terminator expecteds and keep only _parser expecteds.Add(ref itemExpecteds); } terminatorExpecteds.Dispose(); itemExpecteds.Dispose(); result = null; return(false); } // throw out both sets of expecteds terminatorExpecteds.Clear(); itemExpecteds.Clear(); if (!itemConsumedInput) { throw new InvalidOperationException("Until() used with a parser which consumed no input"); } ts?.Add(itemResult); } }
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out IEnumerable <T> result) { var success = _parser.TryParse(ref state, ref expecteds, out var result1); if (!success) { // state.Error set by _parser result = null; return(false); } var ts = new List <T> { result1 }; var childExpecteds = new ExpectedCollector <TToken>(); while (true) { var sepStartLoc = state.Location; var sepSuccess = _separator.TryParse(ref state, ref childExpecteds, out var _); var sepConsumedInput = state.Location > sepStartLoc; expecteds.AddIf(ref childExpecteds, !sepSuccess && sepConsumedInput); childExpecteds.Clear(); if (!sepSuccess) { childExpecteds.Dispose(); if (sepConsumedInput) { // state.Error set by _separator result = null; return(false); } result = ts; return(true); } var itemStartLoc = state.Location; var itemSuccess = _parser.TryParse(ref state, ref childExpecteds, out var itemResult); var itemConsumedInput = state.Location > itemStartLoc; expecteds.AddIf(ref childExpecteds, !itemSuccess && itemConsumedInput); childExpecteds.Clear(); if (!itemSuccess) { childExpecteds.Dispose(); if (itemConsumedInput) { // state.Error set by _parser result = null; return(false); } result = ts; return(true); } ts.Add(itemResult); } }
public ParseError <TToken> BuildError(ref ExpectedCollector <TToken> expecteds) => new ParseError <TToken>(_unexpected, _eof, expecteds.ToImmutableArray(), ComputeSourcePosAt(_errorLocation), _message);
internal sealed override bool TryParse(ref ParseState <TToken> state, ref ExpectedCollector <TToken> expecteds, out T result) => _lazy.Value.TryParse(ref state, ref expecteds, out result);