示例#1
0
        /// <inheritdoc/>
        public override IReply <TValue> Parse(TokenStream tokens)
        {
            var left = _left.ParseGenerally(tokens);

            if (!left.Success)
            {
                return(Failure <TValue> .From(left));
            }

            var item = _item.Parse(left.UnparsedTokens);

            if (!item.Success)
            {
                return(item);
            }

            var right = _right.ParseGenerally(item.UnparsedTokens);

            if (!right.Success)
            {
                return(Failure <TValue> .From(right));
            }

            return(new Success <TValue>(item.ParsedValue, right.UnparsedTokens, right.FailureMessages));
        }
示例#2
0
        /// <inheritdoc/>
        public override IReply <KeyValuePair <TName, TValue> > Parse(TokenStream tokens)
        {
            var name = _name.Parse(tokens);

            if (!name.Success)
            {
                return(Failure <KeyValuePair <TName, TValue> > .From(name));
            }

            var delimiter = _delimiter.ParseGenerally(name.UnparsedTokens);

            if (!delimiter.Success)
            {
                return(Failure <KeyValuePair <TName, TValue> > .From(delimiter));
            }

            var value = _value.Parse(delimiter.UnparsedTokens);

            if (!value.Success)
            {
                return(Failure <KeyValuePair <TName, TValue> > .From(value));
            }

            return(new Success <KeyValuePair <TName, TValue> >(new KeyValuePair <TName, TValue>(name.ParsedValue, value.ParsedValue), value.UnparsedTokens, value.FailureMessages));
        }
示例#3
0
        /// <inheritdoc/>
        public override IReply <TValue> Parse(TokenStream tokens)
        {
            var skip = _skip.ParseGenerally(tokens);

            if (!skip.Success)
            {
                return(Failure <TValue> .From(skip));
            }

            return(_take.Parse(skip.UnparsedTokens));
        }
示例#4
0
        /// <inheritdoc/>
        public override IReply <TResult> Parse(TokenStream tokens)
        {
            var reply = _parser.Parse(tokens);

            if (!reply.Success)
            {
                return(Failure <TResult> .From(reply));
            }

            var parsedValue = _resultContinuation(reply.ParsedValue);

            return(new Success <TResult>(parsedValue, reply.UnparsedTokens));
        }
示例#5
0
        /// <inheritdoc/>
        public override IReply <TValue> Parse(TokenStream tokens)
        {
            var take = _take.Parse(tokens);

            if (!take.Success)
            {
                return(Failure <TValue> .From(take));
            }

            var skip = _skip.ParseGenerally(take.UnparsedTokens);

            if (!skip.Success)
            {
                return(Failure <TValue> .From(skip));
            }

            return(new Success <TValue>(take.ParsedValue, skip.UnparsedTokens, skip.FailureMessages));
        }
示例#6
0
        /// <inheritdoc/>
        public override IReply <TValue[]> Parse(TokenStream tokens)
        {
            var tokensToParse = tokens ?? throw new ArgumentNullException(nameof(tokens));

            var parsersLength = _items.Length;

            var result      = new TValue[parsersLength];
            var parsersUsed = new bool[parsersLength];
            var parsersToGo = parsersLength;

            var separatorParserIsPresent = _separator != null;

            var failures = FailureMessages.Empty;

            var atLeastOneItemParsed = false;

            var separatorWasTheLastTokenParsed = false;

            for (var i = 0; i < parsersLength; ++i)
            {
                if (parsersUsed[i])
                {
                    continue;
                }

                if (separatorParserIsPresent && atLeastOneItemParsed && !separatorWasTheLastTokenParsed)
                {
                    var positionBeforeSeparator = tokensToParse.Position;
                    var separatorReply          = _separator.ParseGenerally(tokensToParse);
                    var positionAfterSeparator  = separatorReply.UnparsedTokens.Position;

                    separatorWasTheLastTokenParsed = separatorReply.Success;

                    if (separatorWasTheLastTokenParsed)
                    {
                        if (positionBeforeSeparator == positionAfterSeparator)
                        {
                            throw new Exception($"Separator parser {_separator.Expression} encountered a potential infinite loop at position {positionBeforeSeparator}.");
                        }
                    }
                    else
                    {
                        if (positionBeforeSeparator != positionAfterSeparator || _mode == UnorderedParsingMode.FullSet)
                        {
                            return(Failure <TValue[]> .From(separatorReply));
                        }
                    }

                    tokensToParse = separatorReply.UnparsedTokens;
                }

                var oldPosition = tokensToParse.Position;
                var reply       = _items[i].Parse(tokensToParse);
                var newPosition = reply.UnparsedTokens.Position;

                tokensToParse = reply.UnparsedTokens;

                if (reply.Success)
                {
                    if (newPosition == oldPosition)
                    {
                        throw new Exception($"Item parser {_items[i].Expression} encountered a potential infinite loop at position {newPosition}.");
                    }

                    result[i]      = reply.ParsedValue;
                    parsersUsed[i] = true;
                    --parsersToGo;

                    i = -1; // start from the beginning of _parsers
                    atLeastOneItemParsed           = true;
                    separatorWasTheLastTokenParsed = false;
                    failures = FailureMessages.Empty;

                    continue;
                }
                else if (newPosition != oldPosition)
                {
                    return(Failure <TValue[]> .From(reply));
                }

                failures = failures.Merge(reply.FailureMessages);

                var triedAllParsers = i == parsersLength - 1;

                if (newPosition != oldPosition || (triedAllParsers && (separatorWasTheLastTokenParsed || _mode == UnorderedParsingMode.FullSet)))
                {
                    return(new Failure <TValue[]>(reply.UnparsedTokens, failures));
                }
            }

            if ((parsersToGo > 0 && _mode == UnorderedParsingMode.FullSet) || (!atLeastOneItemParsed && _mode == UnorderedParsingMode.NonemptySubset))
            {
                return(new Failure <TValue[]>(tokensToParse, failures));
            }

            return(new Success <TValue[]>(result, tokensToParse));
        }
示例#7
0
        /// <inheritdoc/>
        public override IGeneralReply ParseGenerally(TokenStream tokens)
        {
            if (tokens == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            var oldPosition = tokens.Position;
            var reply       = _item.ParseGenerally(tokens);
            var newPosition = reply.UnparsedTokens.Position;

            var times = 0;

            var separatorParserIsPresent = _separator != null;
            var separatorWasParsed       = false;

            while (reply.Success)
            {
                if (oldPosition == newPosition)
                {
                    throw new Exception($"Item parser {_item.Expression} encountered a potential infinite loop at position {newPosition}.");
                }

                ++times;

                switch (_quantificationRule)
                {
                case QuantificationRule.ExactlyN:
                    if (times > _n)
                    {
                        return(new GeneralFailure(
                                   reply.UnparsedTokens,
                                   FailureMessages.Empty.With(FailureMessage.Expected($"{_item.Expression} occurring no more than exactly {_n} times"))));
                    }
                    break;

                case QuantificationRule.NtoM:
                    if (times > _m)
                    {
                        return(new GeneralFailure(
                                   reply.UnparsedTokens,
                                   FailureMessages.Empty.With(FailureMessage.Expected($"{_item.Expression} occurring no more than between {_n} and {_m} times"))));
                    }
                    break;

                case QuantificationRule.NOrLess:
                    if (times > _n)
                    {
                        return(new GeneralFailure(
                                   reply.UnparsedTokens,
                                   FailureMessages.Empty.With(FailureMessage.Expected($"{_item.Expression} occurring no more than {_n} times"))));
                    }
                    break;
                }

                var unparsedTokens = reply.UnparsedTokens;

                if (separatorParserIsPresent)
                {
                    var positionBeforeSeparator = newPosition;

                    var separatorReply = _separator.ParseGenerally(reply.UnparsedTokens);

                    unparsedTokens = separatorReply.UnparsedTokens;

                    var positionAfterSeparator = unparsedTokens.Position;

                    if (separatorReply.Success)
                    {
                        if (positionBeforeSeparator == positionAfterSeparator)
                        {
                            throw new Exception($"Separator parser {_separator.Expression} encountered a potential infinite loop at position {positionBeforeSeparator}.");
                        }
                    }
                    else
                    {
                        if (positionBeforeSeparator != positionAfterSeparator)
                        {
                            return(Failure <TValue[]> .From(separatorReply));
                        }
                    }

                    newPosition = positionAfterSeparator;

                    separatorWasParsed = separatorReply.Success;
                }

                oldPosition = newPosition;

                if (separatorParserIsPresent && !separatorWasParsed)
                {
                    break;
                }

                reply = _item.ParseGenerally(unparsedTokens);

                if (!reply.Success && separatorParserIsPresent)
                {
                    return(new GeneralFailure(reply.UnparsedTokens, reply.FailureMessages));
                }

                newPosition = reply.UnparsedTokens.Position;
            }

            //The item parser finally failed or the separator parser parsed the next separator, but there was no item following it
            if (oldPosition != newPosition || separatorParserIsPresent && separatorWasParsed)
            {
                return(new GeneralFailure(reply.UnparsedTokens, reply.FailureMessages));
            }

            switch (_quantificationRule)
            {
            case QuantificationRule.NOrMore:
                if (times < _n)
                {
                    return(new GeneralFailure(
                               reply.UnparsedTokens,
                               FailureMessages.Empty.With(FailureMessage.Expected($"{_item.Expression} occurring {_n}+ times"))
                               ));
                }
                break;

            case QuantificationRule.ExactlyN:
                if (times != _n)
                {
                    return(new GeneralFailure(
                               reply.UnparsedTokens,
                               FailureMessages.Empty.With(FailureMessage.Expected(
                                                              $"{_item.Expression} occurring no {(times > _n ? "more" : "less")} than exactly {_n} times")
                                                          )));
                }
                break;

            case QuantificationRule.NtoM:
                if (times < _n)
                {
                    return(new GeneralFailure(
                               reply.UnparsedTokens,
                               FailureMessages.Empty.With(FailureMessage.Expected($"{_item.Expression} occurring no less than between {_n} and {_m} times"))
                               ));
                }
                break;

            case QuantificationRule.NOrLess:
                if (times > _n)
                {
                    return(new GeneralFailure(
                               reply.UnparsedTokens,
                               FailureMessages.Empty.With(FailureMessage.Expected($"{_item.Expression} occurring no more than {_n} times"))
                               ));
                }
                break;
            }

            return(new GeneralSuccess(reply.UnparsedTokens));
        }