Beispiel #1
0
 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);
 }
Beispiel #2
0
 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);
 }
Beispiel #3
0
        /// <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));
        }
Beispiel #6
0
        /// <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();
                });
            }));
        }
Beispiel #7
0
        /// <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);
            }));
        }
Beispiel #11
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)));
        }
        /// <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));
        }
Beispiel #13
0
        /// <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()));
        }
Beispiel #15
0
        /// <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));
        }
Beispiel #16
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>()));
        }
Beispiel #17
0
        /// <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())));
        }
Beispiel #19
0
        /// <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))));
        }
Beispiel #22
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));
        }
Beispiel #23
0
        /// <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));
        }
Beispiel #24
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));
        }
Beispiel #25
0
 public InlineStringObservableParser()
 {
     start = new AnonymousObservableParser <char, TResult>(
         "Inline",
         () => Next,
         source =>
     {
         throw new NotSupportedException(Properties.Errors.InlineParserWithoutGrammar);
     });
 }
Beispiel #26
0
        /// <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())));
        }
Beispiel #27
0
        /// <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));
        }
Beispiel #28
0
        /// <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)));
        }
Beispiel #29
0
        /// <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)));
        }
Beispiel #30
0
        /// <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))));
        }