Example #1
0
        /// <summary>
        /// Concatenates the specified parse result value sequences into a new parse result value sequence.
        /// The lengths are summed to indicate that the new parse result encompasses all of the specified
        /// parse results and that they match consecutively in the input sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The parse result value sequence to which <paramref name="otherResults"/> will be concatenated.</param>
        /// <param name="otherResults">Zero or more parse result value sequences to be concatenated to the value sequence of <paramref name="firstResult"/>.</param>
        /// <returns>A new <see cref="IParseResult{TResult}"/> object containing the sum of the specified parse results' lengths and the
        /// concatenation of their values.</returns>
        public static IParseResult <IEnumerable <TResult> > Concat <TResult>(
            this IParseResult <IEnumerable <TResult> > firstResult,
            IEnumerable <IParseResult <IEnumerable <TResult> > > otherResults)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(firstResult.Value != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <IEnumerable <TResult> >));
            Contract.Requires(otherResults != null);
            Contract.Ensures(Contract.Result <IParseResult <IEnumerable <TResult> > >() != null);

            IParseResult <IEnumerable <TResult> > lastResult = null;

            int length = firstResult.Length;

            var value = firstResult.Value.ConcatOptimized(
                otherResults.Do(
                    result =>
            {
                lastResult = result;
                length    += result.Length;
            })
                .Select(result => result.Value));

            if (lastResult == null)
            {
                return(firstResult);
            }
            else
            {
                // yield from lastResult to support ILookAheadParseResult
                return(lastResult.Yield(value, length));
            }
        }
Example #2
0
        /// <summary>
        /// Clones the specified <paramref name="result"/>.
        /// </summary>
        /// <typeparam name="TValue">The type of the parse result's value.</typeparam>
        /// <param name="result">The <see cref="IParseResult{TValue}"/> from which to create a new parse result.</param>
        /// <returns>A new <see cref="IParseResult{TValue}"/> with the same length and value as the
        /// specified <paramref name="result"/>.</returns>
        public static IParseResult <TValue> Yield <TValue>(
            this IParseResult <TValue> result)
        {
            Contract.Requires(result != null);
            Contract.Ensures(Contract.Result <IParseResult <TValue> >() != null);

            return(result.Yield(result.Value, result.Length));
        }
Example #3
0
        /// <summary>
        /// Creates a new parse result with the value returned by the specified selector and the length of the
        /// specified <paramref name="result"/>.
        /// </summary>
        /// <typeparam name="TOldValue">The type of the old parse result's value.</typeparam>
        /// <typeparam name="TNewValue">The type of the new parse result's value</typeparam>
        /// <param name="result">The <see cref="IParseResult{TOldValue}"/> that provides the length.</param>
        /// <param name="valueSelector">A function that selects the value for the new parse result.</param>
        /// <returns>A new <see cref="IParseResult{TValue}"/> with the value returned by the specified selector
        /// and the length of the specified <paramref name="result"/>.</returns>
        public static IParseResult <TNewValue> Yield <TOldValue, TNewValue>(
            this IParseResult <TOldValue> result,
            Func <TOldValue, TNewValue> valueSelector)
        {
            Contract.Requires(result != null);
            Contract.Requires(valueSelector != null);
            Contract.Ensures(Contract.Result <IParseResult <TNewValue> >() != null);

            return(result.Yield(valueSelector(result.Value), result.Length));
        }
Example #4
0
        /// <summary>
        /// Concatenates the specified scalar parse result value and parse result value sequence into a new parse result value sequence.
        /// The lengths are summed to indicate that the new parse result
        /// encompasses both of the specified parse results and that they match consecutively
        /// in the input sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The scalar parse result value to which <paramref name="secondResult"/> will be concatenated.</param>
        /// <param name="secondResult">The parse result value sequence to be concatenated to the value of <paramref name="firstResult"/>.</param>
        /// <returns>A new <see cref="IParseResult{TResult}"/> object containing the sum of the specified parse results'
        /// lengths and the concatenation of their values.</returns>
        public static IParseResult <IEnumerable <TResult> > Concat <TResult>(
            this IParseResult <TResult> firstResult,
            IParseResult <IEnumerable <TResult> > secondResult)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <TResult>));
            Contract.Requires(secondResult != null);
            Contract.Requires(secondResult.Value != null);
            Contract.Ensures(Contract.Result <IParseResult <IEnumerable <TResult> > >() != null);

            return(secondResult.Yield(
                       secondResult.Value.StartWith(firstResult.Value),
                       firstResult.Length + secondResult.Length));
        }
Example #5
0
        /// <summary>
        /// Concatenates the specified parse result value sequence and scalar parse result value into a new parse result value sequence.
        /// The lengths are summed to indicate that the new parse result
        /// encompasses both of the specified parse results and that they match consecutively
        /// in the input sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The parse result value sequence to which <paramref name="secondResult"/> will be concatenated.</param>
        /// <param name="secondResult">The scalar parse result value to be concatenated to the value of <paramref name="firstResult"/>.</param>
        /// <returns>A new <see cref="IParseResult{TResult}"/> object containing the sum of the specified parse results' lengths and
        /// the concatenation of their values.</returns>
        public static IParseResult <IEnumerable <TResult> > Concat <TResult>(
            this IParseResult <IEnumerable <TResult> > firstResult,
            IParseResult <TResult> secondResult)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(firstResult.Value != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <IEnumerable <TResult> >));
            Contract.Requires(secondResult != null);
            Contract.Ensures(Contract.Result <IParseResult <IEnumerable <TResult> > >() != null);

            return(secondResult.Yield(
                       firstResult.Value.ConcatOptimized(new[] { secondResult.Value }),
                       firstResult.Length + secondResult.Length));
        }
        /// <summary>
        /// Concatenates the specified parse result value sequence and scalar parse result value into a new parse result value sequence.
        /// The lengths are summed to indicate that the new parse result
        /// encompasses both of the specified parse results and that they match consecutively
        /// in the input sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The parse result value sequence to which <paramref name="secondResult"/> will be concatenated.</param>
        /// <param name="secondResult">The scalar parse result value to be concatenated to the value of <paramref name="firstResult"/>.</param>
        /// <returns>A new <see cref="IParseResult{TResult}"/> object containing the sum of the specified parse results' lengths and
        /// the concatenation of their values.</returns>
        public static IParseResult <IObservable <TResult> > Concat <TResult>(
            this IParseResult <IObservable <TResult> > firstResult,
            IParseResult <TResult> secondResult)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(firstResult.Value != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <IObservable <TResult> >));
            Contract.Requires(secondResult != null);
            Contract.Ensures(Contract.Result <IParseResult <IObservable <TResult> > >() != null);

            return(secondResult.Yield(
                       firstResult.Value.Concat(Observable.Return(secondResult.Value)),
                       firstResult.Length + secondResult.Length));
        }
Example #7
0
        /// <summary>
        /// Applies a selector function to two parse results to produce a new parse result.
        /// The lengths are summed to indicate that the new parse result
        /// encompasses both of the specified parse results and that they match consecutively
        /// in the input sequence.
        /// </summary>
        /// <typeparam name="TFirstResult">The type of the first parse result's value.</typeparam>
        /// <typeparam name="TSecondResult">The type of the second parse result's value.</typeparam>
        /// <typeparam name="TResult">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The parse result to be combined with <paramref name="secondResult"/>.</param>
        /// <param name="secondResult">The parse result to be combined with <paramref name="firstResult"/>.</param>
        /// <param name="resultSelector">A function that selects a new parse result from the two specified parse results.</param>
        /// <returns>A new <see cref="IParseResult{TResult}"/> object containing the sum of the specified parse results'
        /// lengths and the return value of the <paramref name="resultSelector"/> function.</returns>
        public static IParseResult <TResult> Add <TFirstResult, TSecondResult, TResult>(
            this IParseResult <TFirstResult> firstResult,
            IParseResult <TSecondResult> secondResult,
            Func <TFirstResult, TSecondResult, TResult> resultSelector)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <TFirstResult>));
            Contract.Requires(secondResult != null);
            Contract.Requires(resultSelector != null);
            Contract.Ensures(Contract.Result <IParseResult <TResult> >() != null);

            return(secondResult.Yield(
                       resultSelector(firstResult.Value, secondResult.Value),
                       firstResult.Length + secondResult.Length));
        }
Example #8
0
        /// <summary>
        /// Creates a new parse result from a parse result and another value with the length and value
        /// returned by the specified selectors.
        /// </summary>
        /// <typeparam name="TOldValue">The type of the old parse result's value.</typeparam>
        /// <typeparam name="TOther">The type of the other value.</typeparam>
        /// <typeparam name="TNewValue">The type of the new parse result's value.</typeparam>
        /// <param name="result">The old parse result from which to create a new parse result.</param>
        /// <param name="other">The other value from which to create a new parse result.</param>
        /// <param name="valueSelector">A function that selects the value for the new parse result.</param>
        /// <param name="lengthSelector">A function that selects the length for the new parse result.</param>
        /// <returns>A new <see cref="IParseResult{TValue}"/> with the length and value returned by the
        /// specified selectors.</returns>
        public static IParseResult <TNewValue> Yield <TOldValue, TOther, TNewValue>(
            this IParseResult <TOldValue> result,
            TOther other,
            Func <TOldValue, TOther, TNewValue> valueSelector,
            Func <IParseResult <TOldValue>, TOther, int> lengthSelector)
        {
            Contract.Requires(result != null);
            Contract.Requires(other != null);
            Contract.Requires(valueSelector != null);
            Contract.Requires(lengthSelector != null);
            Contract.Ensures(Contract.Result <IParseResult <TNewValue> >() != null);

            int length = lengthSelector(result, other);

            Contract.Assume(length >= 0);

            return(result.Yield(
                       valueSelector(result.Value, other),
                       length));
        }
Example #9
0
        /// <summary>
        /// Creates a new parse result from two parse results with the length and value returned
        /// by the specified selectors.
        /// </summary>
        /// <typeparam name="TFirstValue">The type of the first parse result's value.</typeparam>
        /// <typeparam name="TSecondValue">The type of the second parse result's value.</typeparam>
        /// <typeparam name="TNewValue">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The first parse result.</param>
        /// <param name="secondResult">The second parse result.</param>
        /// <param name="valueSelector">A function that selects the value for the new parse result.</param>
        /// <param name="lengthSelector">A function that selects the length for the new parse result.</param>
        /// <returns>A new <see cref="IParseResult{TValue}"/> with the length and value returned by the
        /// specified selectors.</returns>
        public static IParseResult <TNewValue> Yield <TFirstValue, TSecondValue, TNewValue>(
            this IParseResult <TFirstValue> firstResult,
            IParseResult <TSecondValue> secondResult,
            Func <TFirstValue, TSecondValue, TNewValue> valueSelector,
            Func <IParseResult <TFirstValue>, IParseResult <TSecondValue>, int> lengthSelector)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <TFirstValue>));
            Contract.Requires(secondResult != null);
            Contract.Requires(valueSelector != null);
            Contract.Requires(lengthSelector != null);
            Contract.Ensures(Contract.Result <IParseResult <TNewValue> >() != null);

            int length = lengthSelector(firstResult, secondResult);

            Contract.Assume(length >= 0);

            return(secondResult.Yield(
                       valueSelector(firstResult.Value, secondResult.Value),
                       length));
        }
        /// <summary>
        /// Concatenates the specified parse result value sequences into a new parse result value sequence.
        /// The lengths are summed to indicate that the new parse result encompasses all of the specified
        /// parse results and that they match consecutively in the input sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the new parse result's value.</typeparam>
        /// <param name="firstResult">The parse result value sequence to which <paramref name="otherResults"/> will be concatenated.</param>
        /// <param name="otherResults">Zero or more parse result value sequences to be concatenated to the value sequence of <paramref name="firstResult"/>.</param>
        /// <returns>A new <see cref="IParseResult{TResult}"/> object containing the sum of the specified parse results' lengths and the
        /// concatenation of their values.</returns>
        public static IParseResult <IObservable <TResult> > Concat <TResult>(
            this IParseResult <IObservable <TResult> > firstResult,
            IEnumerable <IParseResult <IObservable <TResult> > > otherResults)
        {
            Contract.Requires(firstResult != null);
            Contract.Requires(firstResult.Value != null);
            Contract.Requires(!(firstResult is ILookAheadParseResult <IObservable <TResult> >));
            Contract.Requires(otherResults != null);
            Contract.Ensures(Contract.Result <IParseResult <IObservable <TResult> > >() != null);

            IParseResult <IObservable <TResult> > lastResult = null;

            int length = firstResult.Length;

            foreach (var result in otherResults)
            {
                Contract.Assume(result != null);

                lastResult = result;
                length    += result.Length;
            }

            if (lastResult == null)
            {
                return(firstResult);
            }
            else
            {
                // yield from lastResult to support ILookAheadParseResult
                return(lastResult.Yield(
                           otherResults
                           .StartWith(firstResult)
                           .Select(result => result.Value)
                           .Concat(),
                           length));
            }
        }