/// <summary>
        /// This is the "trampoline" function
        /// </summary>
        /// <param name="workList"></param>
        /// <param name="input"></param>
        /// <param name="log"></param>
        /// <typeparam name="TInput"></typeparam>
        /// <returns></returns>
        private static WorkList <TInput> Apply <TInput>(WorkList <TInput> workList, TInput input, Action <string> log)
        {
            log($"Input: '{input}'");
            var(matchers, initialParsers) = workList;
            var parsers = new Queue <RegisterParser <TInput> >(initialParsers);

            var registrar = new ParserRegistrar <TInput>();

            log("Creating new work");
            while (parsers.Count > 0)
            {
                foreach (var registration in parsers.Dequeue()(registrar))
                {
                    parsers.Enqueue(registration);
                }
            }

            matchers = matchers.AddRange(registrar.GetWork());
            log("Apply input to work");
            return(matchers.Select(matcher => matcher(input)).Aggregate((a, b) => a.Add(b)));
        }
Exemple #2
0
 /// <summary>
 /// Determines if a work list is empty (has no matchers or parser registrations).
 /// </summary>
 /// <param name="this">This work list</param>
 /// <typeparam name="TInput">Input element type</typeparam>
 /// <returns><code>true</code> if the work list has no matchers or parser registrations</returns>
 public static bool IsEmpty <TInput>(this WorkList <TInput> @this) =>
 @this.Matchers.IsEmpty && @this.Parsers.IsEmpty;
Exemple #3
0
 /// <summary>
 /// Creates a new <see cref="WorkList{T}"/> with the work from this list and an additional parser to start.
 /// </summary>
 /// <param name="this">This work list</param>
 /// <param name="parser">Parser to be started</param>
 /// <param name="resolver">Resolver to invoke when the parser matches</param>
 /// <typeparam name="TInput">Input element type</typeparam>
 /// <typeparam name="TMatch">Parse result type</typeparam>
 /// <returns>The new work list</returns>
 public static WorkList <TInput> Add <TInput, TMatch>(this WorkList <TInput> @this, IParser <TInput, TMatch> parser, Resolver <TInput, TMatch> resolver) =>
 new WorkList <TInput>(@this.Matchers, @this.Parsers.Add(r => r.Register(parser, resolver)));
Exemple #4
0
 /// <summary>
 /// Creates a new <see cref="WorkList{T}"/> with the work from this list and additional matchers.
 /// </summary>
 /// <param name="this">This work list</param>
 /// <param name="matchers">Matchers to add</param>
 /// <typeparam name="TInput">Input element type</typeparam>
 /// <returns>The new work list</returns>
 public static WorkList <TInput> Add <TInput>(this WorkList <TInput> @this, params Matcher <TInput>[] matchers) =>
 new WorkList <TInput>(@this.Matchers.AddRange(matchers), @this.Parsers);
Exemple #5
0
 /// <summary>
 /// Creates a new <see cref="WorkList{T}"/> with the combined work of this list and another.
 /// </summary>
 /// <param name="this">This work list</param>
 /// <param name="other">Work list to add</param>
 /// <typeparam name="TInput">Input element type</typeparam>
 /// <returns>The new work list</returns>
 public static WorkList <TInput> Add <TInput>(this WorkList <TInput> @this, WorkList <TInput> other) =>
 new WorkList <TInput>(@this.Matchers.AddRange(other.Matchers), @this.Parsers.AddRange(other.Parsers));