/// <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)); } }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); } }