public IObservableParser <char, XElement> Element(string name, IObservableParser <char, IObservable <XObject> > content) { Contract.Requires(!string.IsNullOrWhiteSpace(name)); Contract.Requires(content != null); Contract.Ensures(Contract.Result <IObservableParser <char, XElement> >() != null); return(null); }
public IObservableParser <char, XElement> Element(IObservableParser <char, IObservable <XAttribute> > attributes, IObservableParser <char, IObservable <XObject> > content) { Contract.Requires(attributes != null); Contract.Requires(content != null); Contract.Ensures(Contract.Result <IObservableParser <char, XElement> >() != null); return(null); }
/// <summary> /// Matches the specified <paramref name="parser"/> or yields the specified default result if there are /// no matches. /// </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 that might produce matches.</param> /// <param name="defaultResult">The value that is yielded if the specified <paramref name="parser"/> does not match.</param> /// <returns>A parser that yields matches from the specified <paramref name="parser"/> or the specified default result /// if the <paramref name="parser"/> does not match.</returns> public static IObservableParser <TSource, TResult> WithDefault <TSource, TResult>( this IObservableParser <TSource, TResult> parser, TResult defaultResult) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Yield( "WithDefault", (source, observer) => { bool hasResult = false; return parser.Parse(source).SubscribeSafe( result => { hasResult = true; observer.OnNext(result); }, observer.OnError, () => { if (!hasResult) { observer.OnNext(ParseResult.Create(defaultResult, length: 0)); } observer.OnCompleted(); }); })); }
internal ObservableParserQueryContext(IObservableParser <TSource, TResult> parser, TQueryValue value) { Contract.Requires(parser != null); this.parser = parser; this.queryValue = value; }
public static IObservable <TResult> Parse <TSource, TResult>( this IObservable <TSource> source, Func <ObservableParserQueryContext <TSource, TSource, IObservableParser <TSource, TSource> >, ObservableParserQueryContext <TSource, TSource, IObservableParser <TSource, TResult> > > grammarSelector) { Contract.Requires(source != null); Contract.Requires(grammarSelector != null); Contract.Ensures(Contract.Result <IObservable <TResult> >() != null); var parser = new InlineObservableParser <TSource, TResult>(); var proxyParser = (IObservableParser <TSource, TSource>)parser; // The proxy allows the grammar author to use base methods such as Success and Failure // while still allowing type inference to work correctly; i.e., the Parse method is unavailable // and thus the type of the proxy is based solely on TSource, without requiring TResult to // be in an input position in grammarSelector. var context = new ObservableParserQueryContext <TSource, TSource, IObservableParser <TSource, TSource> >( proxyParser, parser.Next); var grammar = grammarSelector(context); Contract.Assume(grammar != null); IObservableParser <TSource, TResult> start = grammar.Value; Contract.Assume(start != null); // enableBranchOptimizations must be false: See the comments in the first interactive Rxx.Parsers.Linq.Parser.Parse method for details. return(parser.Parse(source.ToCursor(forwardOnly: true, enableBranchOptimizations: false), start)); }
/// <summary> /// Matches the specified <paramref name="parser"/> or yields success without a value when it does not match. /// </summary> /// <typeparam name="TSource">The type of the source elements.</typeparam> /// <typeparam name="TResult">The type of the elements of the result sequences that are generated from parsing the source elements.</typeparam> /// <param name="parser">The parser that might produce matches.</param> /// <returns>A parser that yields matches from the specified <paramref name="parser"/> or /// an empty observable sequence to indicate success when it does not match.</returns> public static IObservableParser <TSource, IObservable <TResult> > Maybe <TSource, TResult>( this IObservableParser <TSource, IObservable <TResult> > parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null); return(parser.Yield( "Maybe", (source, observer) => { bool hasResult = false; return parser.Parse(source).SubscribeSafe( result => { hasResult = true; observer.OnNext(result); }, observer.OnError, () => { if (!hasResult) { observer.OnNext(ObservableParseResult.SuccessMany <TResult>(length: 0)); } observer.OnCompleted(); }); })); }
/// <summary> /// Yields success when the specified <paramref name="parser"/> does not match. /// </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 for which any match results in failure.</param> /// <returns>A parser that yields failure when the specified <paramref name="parser"/> matches or /// an empty sequence to indicate success when it does not match.</returns> public static IObservableParser <TSource, IObservable <TResult> > None <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null); if (parser is IObservableParserCursor <TSource> ) { return(parser.AtEndOfSequence()); } else { return(parser.Yield <TSource, TResult, IObservable <TResult> >( "None", (source, observer) => { return parser.Parse(source).Any().SubscribeSafe( any => { if (!any) { observer.OnNext(ObservableParseResult.SuccessMany <TResult>(length: 0)); } }, observer.OnError, observer.OnCompleted); })); } }
public AmbiguousObservableParser(IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); this.parser = parser; this.untilCount = unlimitedCount; }
private IObservableParser <char, IObservable <XObject> > Content( out IObservableParser <char, IObservable <XAttribute> > attributes, IEnumerable <IObservableParser <char, XObject> > content) { Contract.Requires(content != null); Contract.Ensures(Contract.ValueAtReturn(out attributes) != null); Contract.Ensures(Contract.Result <IObservableParser <char, IObservable <XObject> > >() != null); var contentList = content.ToList(); var attributeList = contentList.OfType <IObservableParser <char, XAttribute> >().ToList(); var anyAttribute = attribute(_ => true); Contract.Assume(anyAttribute != null); attributes = (attributeList.Count == 0) ? anyAttribute.None() : attributeList.AllUnordered(); foreach (var a in attributeList) { contentList.Remove(a); } var contentWithComments = new List <IObservableParser <char, IObservable <XObject> > >(contentList.Count); foreach (var item in contentList) { Contract.Assume(item != null); contentWithComments.Add(Comment.Maybe().And(item)); } /* The original code here used a conditional instead of a full if block to return the result. At runtime, * when targeting Silverlight, it threw an exception: "Operation could destabilize the runtime". I'm not * sure if it was the C# compiler or the Code Contracts rewriter that caused the problem, but expanding it * to a full if block has fixed it. */ IObservableParser <char, IObservable <XObject> > result; if (contentWithComments.Count == 0) { result = from noContent in Content( text => text.Where(node => node.Value.Trim().Length > 0), includeComments: false) // excluding comments actually allows them because of .None() .None() from _ in InsignificantWhiteSpace from comments in comment.NoneOrMore() from __ in InsignificantWhiteSpace select comments; } else { result = contentWithComments.All(); } return(result); }
public IObservable <IParseResult <IObservable <TResult> > > Parse(IObservableCursor <TSource> source) { return(Observable.Defer(() => { firstParser = null; bool first = true; var any = new AnyObservableParser <TSource, TResult>(parsers); var except = new List <IObservableParser <TSource, TResult> >(); // See the AllObservableParser.Parse method for an explanation of the optimization that is provided by SelectMany's TContext argument var root = source.Branch(); var rootDisposable = new RefCountDisposable(root); return ObservableParseResult.ReturnSuccessMany <TResult>(0) .SelectMany( Tuple.Create(root, rootDisposable), parsers.Select( parser => (Func <Tuple <IObservableCursor <TSource>, RefCountDisposable>, Tuple <IParseResult <IObservable <TResult> >, bool>, Tuple <Tuple <IObservableCursor <TSource>, RefCountDisposable>, IObservable <IParseResult <IObservable <TResult> > > > >) ((context, value) => { if (first) { first = false; firstParser = parser; } var branch = context.Item1; var disposable = context.Item2; var refDisposable = disposable.GetDisposable(); IObservable <IParseResult <IObservable <TResult> > > results; // Item2 is only true when value.Item1 is the last element of its sequence. if (value.Item2) { branch.Move(value.Item1.Length); results = any.Parse(except, branch) .Select(result => result.YieldMany()) .Finally(refDisposable.Dispose); } else { branch = branch.Remainder(value.Item1.Length); disposable = new RefCountDisposable(new CompositeDisposable(branch, refDisposable)); results = any.Parse(except, branch) .Select(result => result.YieldMany()) .Finally(disposable.Dispose); } return Tuple.Create(Tuple.Create(branch, disposable), results); })), (firstResult, otherResults) => firstResult.Concat(otherResults)) .Finally(rootDisposable.Dispose); })); }
/// <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))); }
/// <summary> /// Parses multiple sequences with the specified <paramref name="parser"/>, starting from the beginning /// of the source sequence and then skipping one element at a time, until there are no matches or the /// source sequence ends. /// </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 unambiguous parser that will parse each consecutive sequence until there are /// no matches or the source sequence ends.</param> /// <returns>A parser that yields the matches from the specified <paramref name="parser"/> for each /// consecutive sequence, starting from the beginning of the source sequence and then skipping one element /// at a time, until there are no matches or the source sequence ends.</returns> public static IObservableParser <TSource, IObservable <TResult> > Ambiguous <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null); return(new AmbiguousObservableParser <TSource, Unit, TResult>(parser)); }
/// <summary> /// Throws a <see cref="ParseException"/> if the specified <paramref name="parser"/> does not match. /// </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 that must succeed otherwise a <see cref="ParseException"/> is thrown.</param> /// <returns>A parser that yields the matches from the specified <paramref name="parser"/> or throws /// a <see cref="ParseException"/> if there are no matches.</returns> public static IObservableParser <TSource, TResult> Required <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Required(index => new ParseException(index))); }
/// <summary> /// Converts matches from the specified <paramref name="parser"/> into strings. /// </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 from which matches will be converted into strings.</param> /// <returns>A parser that yields strings for the matches from the specified <paramref name="parser"/>.</returns> public static IObservableParser <TSource, string> AsString <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, string> >() != null); return(parser.Select(value => (value == null) ? null : value.ToString())); }
/// <summary> /// Matches the specified <paramref name="parser"/> zero or more times consecutively. /// </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 match zero or more times consecutively.</param> /// <returns>A parser that yields matches from the specified <paramref name="parser"/> zero or more times consecutively.</returns> public static IObservableParser <TSource, IObservable <TResult> > NoneOrMore <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null); return(parser.AtLeast <TSource, TResult, TResult>("NoneOrMore", 0)); }
/// <summary> /// Indicates a failure to parse without actually parsing by returning an empty sequence of parse results. /// </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 that is to fail.</param> /// <returns>A parser that always returns an empty sequence of parse results, starting from the index at which /// the specified <paramref name="parser"/> starts.</returns> public static IObservableParser <TSource, TResult> Failure <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Yield("Failure", source => ObservableParseResult.ReturnFailure <TResult>())); }
/// <summary> /// Appends each element in each result sequence from the specified <paramref name="parser"/> /// to an accumulated <see cref="string"/>, yielding a single <see cref="string"/> per result /// sequence. /// </summary> /// <typeparam name="TSource">The type of the source elements.</typeparam> /// <typeparam name="TIntermediate">The type of the elements that are generated from parsing the source elements.</typeparam> /// <param name="parser">The parser that produces a sequence of result sequences to be joined into strings.</param> /// <returns>A parser that returns the aggregated <see cref="string"/> results.</returns> public static IObservableParser <TSource, string> Join <TSource, TIntermediate>( this IObservableParser <TSource, IObservable <TIntermediate> > parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, string> >() != null); return(Join(parser, v => v, v => v)); }
/// <summary> /// Projects each match from the specified <paramref name="parser"/> into a singleton observable sequence /// that contains the match's value. /// </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 from which matches will be projected into singleton observable sequences.</param> /// <returns>A parser that yields matches from the specified <paramref name="parser"/> projected into singleton /// observable sequences.</returns> public static IObservableParser <TSource, IObservable <TResult> > Amplify <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null); return(parser.Yield("Amplify", source => parser.Parse(source).Select(result => result.YieldMany()))); }
/// <summary> /// Matches the specified <paramref name="parser"/> one or more times consecutively, making the least number of matches possible. /// This is the non-greedy variant of <see cref="OneOrMore{TSource,TResult}(IObservableParser{TSource,TResult})"/>. /// </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 match one or more times consecutively.</param> /// <returns>A parser that yields matches from the specified <paramref name="parser"/> one or more times consecutively, /// making the least number of matches possible.</returns> public static IObservableParser <TSource, IObservable <TResult> > OneOrMoreNonGreedy <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TResult> > >() != null); return(parser.AtLeast <TSource, TResult, TResult>("OneOrMore-NonGreedy", 1, nonGreedy: true)); }
public AmbiguousObservableParser(IObservableParser <TSource, TResult> parser, int untilCount) { Contract.Requires(parser != null); Contract.Requires(untilCount >= 0); this.parser = parser; this.untilCount = untilCount; }
/// <summary> /// Converts greedy matches from the specified <paramref name="parser"/> into matches that /// have a length of zero. /// </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 greedy parser to be made into a non-greedy parser.</param> /// <returns>A parser that converts the greedy matches from the specified <paramref name="parser"/> into /// matches that have a length of zero.</returns> public static IObservableParser <TSource, TResult> NonGreedy <TSource, TResult>( this IObservableParser <TSource, TResult> parser) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Yield("NonGreedy", source => parser.Parse(source).Select(result => result.Yield(length: 0)))); }
/// <summary> /// Matches all results from the specified <paramref name="parser"/> that equal the specified /// <paramref name="value"/>. /// </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 from which matches equivalent to the specified <paramref name="value"/> will be yielded.</param> /// <param name="value">The value to be compared to matches for equality.</param> /// <returns>A parser that matches only those results from the specified <paramref name="parser"/> that equal /// the specified <paramref name="value"/>.</returns> public static IObservableParser <TSource, TResult> Of <TSource, TResult>( this IObservableParser <TSource, TResult> parser, TResult value) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Of(value, EqualityComparer <TResult> .Default)); }
/// <summary> /// Indicates a successful parse operation without actually parsing by yielding the specified scalar <paramref name="result"/>. /// </summary> /// <typeparam name="TSource">The type of the source elements.</typeparam> /// <typeparam name="TIntermediate">The type of the elements that are generated from parsing the source elements.</typeparam> /// <typeparam name="TResult">The type of the <paramref name="result"/>.</typeparam> /// <param name="parser">The parser for which the specified <paramref name="result"/> indicates success.</param> /// <param name="result">The value of the created parser's result.</param> /// <returns>A parser that always returns the specified scalar <paramref name="result"/> with a length /// of zero, starting from the index at which the specified <paramref name="parser"/> starts.</returns> public static IObservableParser <TSource, TResult> Success <TSource, TIntermediate, TResult>( this IObservableParser <TSource, TIntermediate> parser, TResult result) { Contract.Requires(parser != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Success(result, length: 0)); }
private static IObservable <IParseResult <TResult> > SelectManyInternal <TSource, TFirstResult, TSecondResult, TResult>( IObservableCursor <TSource> source, IObservableParser <TSource, TFirstResult> firstParser, Func <TFirstResult, IObservableParser <TSource, TSecondResult> > secondSelector, Func <TFirstResult, TSecondResult, TResult> resultSelector, Func <IParseResult <TFirstResult>, IParseResult <TSecondResult>, int> lengthSelector = null) { Contract.Requires(source != null); Contract.Requires(source.IsForwardOnly); Contract.Requires(firstParser != null); Contract.Requires(secondSelector != null); Contract.Requires(resultSelector != null); Contract.Ensures(Contract.Result <IObservable <IParseResult <TResult> > >() != null); return(from first in firstParser.Parse(source) from second in Observable.Create <IParseResult <TSecondResult> >( observer => { var lookAhead = first as ILookAheadParseResult <TFirstResult>; bool hasResult = false; var remainder = source.Remainder(first.Length); return secondSelector(first.Value) .Parse(remainder) .Finally(remainder.Dispose) .Subscribe( second => { hasResult = true; if (lookAhead != null) { lookAhead.OnCompleted(success: true); observer.OnCompleted(); } else { observer.OnNext(second); } }, observer.OnError, () => { if (!hasResult && lookAhead != null) { lookAhead.OnCompleted(success: false); } observer.OnCompleted(); }); }) select lengthSelector == null ? first.Add(second, resultSelector) : first.Yield(second, resultSelector, lengthSelector)); }
public InlineStringObservableParser() { start = new AnonymousObservableParser <char, TResult>( "Inline", () => Next, source => { throw new NotSupportedException(Properties.Errors.InlineParserWithoutGrammar); }); }
/// <summary> /// Throws a <see cref="ParseException"/> with a message returned by the specified function if the specified /// <paramref name="parser"/> does not match. /// </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 that must succeed otherwise a <see cref="ParseException"/> is thrown.</param> /// <param name="errorMessageFactory">A function that returns a <see cref="string"/> describing the failed expectation /// to be used as the message in the <see cref="ParseException"/>.</param> /// <returns>A parser that yields the matches from the specified <paramref name="parser"/> or throws /// a <see cref="ParseException"/> with a message returned by the specified functions if there are no matches.</returns> public static IObservableParser <TSource, TResult> Required <TSource, TResult>( this IObservableParser <TSource, TResult> parser, Func <string> errorMessageFactory) { Contract.Requires(parser != null); Contract.Requires(errorMessageFactory != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Required(index => new ParseException(index, errorMessageFactory()))); }
/// <summary> /// Matches zero or more values in between the specified <paramref name="open"/> and <paramref name="close"/> parsers. /// </summary> /// <typeparam name="TSource">The type of the source elements.</typeparam> /// <typeparam name="TOpen">The type of the elements that are generated from parsing the <paramref name="open"/> elements.</typeparam> /// <typeparam name="TClose">The type of the elements that are generated from parsing the <paramref name="close"/> elements.</typeparam> /// <param name="open">The parser after which the group begins.</param> /// <param name="close">The parser at which the group ends.</param> /// <returns>A parser with a grammar that matches the <paramref name="open"/> parser, followed by everything up to the first /// match of the <paramref name="close"/> parser, yielding the results in between.</returns> public static IObservableParser <TSource, IObservable <TSource> > Group <TSource, TOpen, TClose>( this IObservableParser <TSource, TOpen> open, IObservableParser <TSource, TClose> close) { Contract.Requires(open != null); Contract.Requires(close != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TSource> > >() != null); return(open.Group(open.Next.Not(close).NoneOrMore(), close)); }
/// <summary> /// Matches everything in between the specified <paramref name="open"/> and <paramref name="close"/> parsers, /// yielding the first unambiguous match as well as everything in between any sub-groups and overlapping groups, /// extending past the unambiguous match of the <paramref name="close"/> parser, that match the same grammar. /// </summary> /// <typeparam name="TSource">The type of the source elements.</typeparam> /// <param name="open">The parser after which the group begins.</param> /// <param name="close">The parser at which the group ends.</param> /// <remarks> /// The same <paramref name="open"/> or <paramref name="close"/> parser may produce multiple matches at the same index. /// </remarks> /// <returns>A parser with a grammar that matches the <paramref name="open"/> parser, followed by everything up to the first /// match of the <paramref name="close"/> parser, yielding the results in between as well as the results of all ambiguous /// matches of the group grammar.</returns> public static IObservableParser <TSource, IObservable <TSource> > AmbiguousGroup <TSource>( this IObservableParser <TSource, TSource> open, IObservableParser <TSource, TSource> close) { Contract.Requires(open != null); Contract.Requires(close != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, IObservable <TSource> > >() != null); return(open.Yield("AmbiguousGroup", source => AmbiguousGroupInternal(source, open, close))); }
/// <summary> /// Invokes the specified <paramref name="action"/> on each result for its side-effects. /// </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 from which results will be supplied to the specified <paramref name="action"/>.</param> /// <param name="action">The method that will be called for each parser result.</param> /// <returns>A new parser that is the same as the specified parser and also invokes the specified /// <paramref name="action"/> with each result for its side-effects.</returns> public static IObservableParser <TSource, TResult> OnSuccess <TSource, TResult>( this IObservableParser <TSource, TResult> parser, Action <IParseResult <TResult> > action) { Contract.Requires(parser != null); Contract.Requires(action != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Yield("OnSuccess", source => parser.Parse(source).Do(action))); }
/// <summary> /// Projects matches from the specified <paramref name="parser"/> into a new form. /// </summary> /// <typeparam name="TSource">The type of the source elements.</typeparam> /// <typeparam name="TIntermediate">The type of the elements that are generated from parsing the source elements.</typeparam> /// <typeparam name="TResult">The type of the elements that are projected from the matches of the specified <paramref name="parser"/>.</typeparam> /// <param name="parser">The parser from which matches will be projected by the specified <paramref name="selector"/> function.</param> /// <param name="selector">A transform function to apply to each match.</param> /// <returns>A parser that projects matches from the specified <paramref name="parser"/> into a new form.</returns> public static IObservableParser <TSource, TResult> Select <TSource, TIntermediate, TResult>( this IObservableParser <TSource, TIntermediate> parser, Func <TIntermediate, TResult> selector) { Contract.Requires(parser != null); Contract.Requires(selector != null); Contract.Ensures(Contract.Result <IObservableParser <TSource, TResult> >() != null); return(parser.Yield("Select", source => parser.Parse(source).Select(result => result.Yield(selector)))); }