Esempio n. 1
0
        /// <summary>
        /// Indicates a successful parse operation without actually parsing by yielding a single result containing an empty sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the source elements.</typeparam>
        /// <typeparam name="TResult">The type of the elements in the sequences that are generated from parsing the source elements.</typeparam>
        /// <param name="parser">The parser for which a single empty result sequence is returned to indicate success.</param>
        /// <remarks>
        /// <see cref="Success{TSource,TResult}(IObservableParser{TSource,IObservable{TResult}})"/> is required as an explicit overload
        /// because the meaning of the parser's result sequence is special and must not be compounded into a sequence of sequences,
        /// which would happen if the <see cref="Success{TSource,TResult}(IObservableParser{TSource,TResult})"/> overload were to be called
        /// instead.
        /// </remarks>
        /// <returns>A parser that returns a single result containing an empty sequence with a length
        /// of zero, starting from the index at which the specified <paramref name="parser"/> starts.</returns>
        public static IObservableParser <TSource, IObservable <TResult> > Success <TSource, TResult>(
            this IObservableParser <TSource, IObservable <TResult> > parser)
        {
            Contract.Requires(parser != null);
            Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null);

            return(parser.Yield("Success", source => ObservableParseResult.ReturnSuccessMany <TResult>(length: 0)));
        }
Esempio n. 2
0
        /// <summary>
        /// Matches the specified <paramref name="parser"/> the specified number of times.
        /// </summary>
        /// <typeparam name="TSource">The type of the source elements.</typeparam>
        /// <typeparam name="TResult">The type of the elements that are generated from parsing the source elements.</typeparam>
        /// <param name="parser">The parser to be matched.</param>
        /// <param name="count">The specified number of times to match the specified <paramref name="parser"/>.</param>
        /// <returns>A parser that matches the specified <paramref name="parser"/> the specified number of times.</returns>
        public static IObservableParser <TSource, IObservable <TResult> > Exactly <TSource, TResult>(
            this IObservableParser <TSource, TResult> parser,
            int count)
        {
            Contract.Requires(parser != null);
            Contract.Requires(count >= 0);
            Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null);

            if (count == 0)
            {
                return(parser.Yield(_ => ObservableParseResult.ReturnSuccessMany <TResult>(length: 0)));
            }
            else if (count == 1)
            {
                // Profiling has shown this to be about 50% faster than Repeat(parser, 1).All()
                return(parser.Amplify());
            }
            else if (parser is IObservableParserCursor <TSource> )
            {
                /* Profiling has shown this to be exponentially faster in next.Exactly(largeN) queries for Ix.
                 * It hasn't been profiled in Rx, but I'm assuming that for similar reasons as Ix it would prove
                 * to be exponentially faster.  Furthermore, due to the extra plumbing in Rx that's being avoided
                 * by this optimization, it may have even greater gains than Ix.
                 */
                return(parser.Yield <TSource, TResult, IObservable <TResult> >(
                           "Exactly",
                           source =>
                           from list in source.Take(count).ToList()
                           where list.Count == count
                           select ParseResult.Create(list.Cast <TResult>().ToObservable(Scheduler.Immediate), count)));
            }
            else
            {
                return(System.Linq.Enumerable.Repeat(parser, count).All());
            }
        }