예제 #1
0
        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);
        }
예제 #2
0
파일: Parser.Not.cs 프로젝트: sambsp/Pidgin
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        // 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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 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);
 }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        // 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));
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
0
        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);
        }
예제 #20
0
        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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        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);
        }
예제 #23
0
        // 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);
            }
        }
예제 #24
0
        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);
            }
        }
예제 #25
0
 public ParseError <TToken> BuildError(ref ExpectedCollector <TToken> expecteds)
 => new ParseError <TToken>(_unexpected, _eof, expecteds.ToImmutableArray(), ComputeSourcePosAt(_errorLocation), _message);
예제 #26
0
 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);