Exemple #1
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);
        }
Exemple #2
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);
        }
Exemple #3
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);
        }
Exemple #4
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);
            }
        }