Пример #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
                    );
                expecteds.Add(Expected);
                result = default;
                return(false);
            }
            var token = state.Current;

            if (!EqualityComparer <TToken> .Default.Equals(token, _token))
            {
                state.Error = new InternalError <TToken>(
                    Maybe.Just(token),
                    false,
                    state.Location,
                    null
                    );
                expecteds.Add(Expected);
                result = default;
                return(false);
            }
            state.Advance();
            result = token;
            return(true);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #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
 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);
 }
Пример #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
        // 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);
            }
        }