internal sealed override InternalResult <TToken> Parse(ref ParseState <TToken> state) { if (!state.HasCurrent) { state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), true, state.SourcePos, null ); state.AddExpected(Expected); return(InternalResult.Failure <TToken>(false)); } var token = state.Current; if (!EqualityComparer <TToken> .Default.Equals(token, _token)) { state.Error = new InternalError <TToken>( Maybe.Just(token), false, state.SourcePos, null ); state.AddExpected(Expected); return(InternalResult.Failure <TToken>(false)); } state.Advance(); return(InternalResult.Success <TToken>(token, true)); }
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 <string> Parse(ref ParseState <char> state) { 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 ); state.AddExpected(Expected); return(InternalResult.Failure <string>(errorPos > 0)); } 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 ); state.AddExpected(Expected); return(InternalResult.Failure <string>(span.Length > 0)); } // OK state.Advance(_value.Length); return(InternalResult.Success <string>(span.ToString(), _value.Length > 0)); }
internal sealed override InternalResult <TEnumerable> Parse(ref ParseState <TToken> state) { 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 ); state.AddExpected(new Expected <TToken>(_valueTokens)); return(InternalResult.Failure <TEnumerable>(errorPos > 0)); } 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 ); state.AddExpected(new Expected <TToken>(_valueTokens)); return(InternalResult.Failure <TEnumerable>(span.Length > 0)); } // OK state.Advance(_valueTokens.Length); return(InternalResult.Success <TEnumerable>(_value, _valueTokens.Length > 0)); }
internal sealed override InternalResult <T> Parse(ref ParseState <TToken> state) { state.Error = new InternalError <TToken>( Maybe.Nothing <TToken>(), false, state.SourcePos, _message ); state.AddExpected(_expected); return(InternalResult.Failure <T>(false)); }
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 sealed override InternalResult <string> Parse(ref ParseState <char> state) { var consumedInput = false; var builder = new InplaceStringBuilder(_value.Length); foreach (var c in _value) { if (!state.HasCurrent) { state.Error = new InternalError <char>( Maybe.Nothing <char>(), true, state.SourcePos, null ); state.AddExpected(Expected); return(InternalResult.Failure <string>(consumedInput)); } var token = state.Current; if (char.ToLowerInvariant(token) != char.ToLowerInvariant(c)) { state.Error = new InternalError <char>( Maybe.Just(token), false, state.SourcePos, null ); state.AddExpected(Expected); return(InternalResult.Failure <string>(consumedInput)); } consumedInput = true; builder.Append(token); state.Advance(); } return(InternalResult.Success <string>(builder.ToString(), 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 <Unit> Parse(ref ParseState <TToken> state) { if (state.HasCurrent) { state.Error = new InternalError <TToken>( Maybe.Just(state.Current), false, state.SourcePos, null ); state.AddExpected(new Expected <TToken>()); return(InternalResult.Failure <Unit>(false)); } return(InternalResult.Success(Unit.Value, false)); }
// 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); } }