Ejemplo n.º 1
0
        /// <summary>
        /// Enables defining in-line parser grammars using LINQ.
        /// </summary>
        /// <typeparam name="TParseSource">The type of the original source elements.</typeparam>
        /// <typeparam name="TParseResult">The type of the elements that are originally generated from parsing the source elements.</typeparam>
        /// <typeparam name="TSource">The type of the source elements; typically, this will be an anonymous compiler-generated type.</typeparam>
        /// <typeparam name="TResult">The type of the elements that are generated from parsing the source elements.</typeparam>
        /// <param name="source">The parser query context to be projected.</param>
        /// <param name="selector">A function that projects the current result of the query context.</param>
        /// <returns>A new query context that is the projection of the specified query context using the specified <paramref name="selector"/>.</returns>
        public static ParserQueryContext <TParseSource, TParseResult, TResult> Select <TParseSource, TParseResult, TSource, TResult>(
            this ParserQueryContext <TParseSource, TParseResult, TSource> source,
            Func <TSource, TResult> selector)
        {
            Contract.Requires(source != null);
            Contract.Requires(selector != null);
            Contract.Ensures(Contract.Result <ParserQueryContext <TParseSource, TParseResult, TResult> >() != null);

            return(new ParserQueryContext <TParseSource, TParseResult, TResult>(
                       source.Parser,
                       selector(source.Value)));
        }
Ejemplo n.º 2
0
        public static IEnumerable <TResult> Parse <TSource, TResult>(
            this IEnumerable <TSource> source,
            Func <ParserQueryContext <TSource, TSource, IParser <TSource, TSource> >,
                  ParserQueryContext <TSource, TSource, IParser <TSource, TResult> > > grammarSelector)
        {
            Contract.Requires(source != null);
            Contract.Requires(grammarSelector != null);
            Contract.Ensures(Contract.Result <IEnumerable <TResult> >() != null);

            var parser      = new InlineParser <TSource, TResult>();
            var proxyParser = (IParser <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 ParserQueryContext <TSource, TSource, IParser <TSource, TSource> >(
                proxyParser,
                parser.Next);

            var grammar = grammarSelector(context);

            Contract.Assume(grammar != null);

            IParser <TSource, TResult> start = grammar.Value;

            Contract.Assume(start != null);

            // enableBranchOptimizations must be false: See the comments in the first Parse extension for details.
            using (var cursor = source.ToCursor(forwardOnly: true, enableBranchOptimizations: false))
            {
                foreach (var result in parser.Parse(cursor, start))
                {
                    yield return(result);
                }
            }
        }