Ejemplo n.º 1
0
    /// <summary>
    /// Search for ReplaceableParsers with the given name and attempt to transform the contents
    /// using the given transformation. The contents of the ReplaceableParser will be replaced
    /// with the transformed result if it is new and valid.
    /// </summary>
    /// <typeparam name="TInput"></typeparam>
    /// <typeparam name="TOutput"></typeparam>
    /// <param name="root"></param>
    /// <param name="predicate"></param>
    /// <param name="transform"></param>
    /// <returns></returns>
    public static MultiReplaceResult ReplaceMulti <TInput, TOutput>(IParser root, Func <IReplaceableParserUntyped, bool> predicate, Func <IMultiParser <TInput, TOutput>, IMultiParser <TInput, TOutput> > transform)
    {
        if (root == null || predicate == null || transform == null)
        {
            return(MultiReplaceResult.Failure());
        }
        var visitor = new FindParserVisitor();
        var state   = new State(p => p is IReplaceableParserUntyped replaceable && predicate(replaceable), true);

        visitor.Visit(root, state);
        var results = new List <SingleReplaceResult>();

        foreach (var found in state.Found.Cast <IReplaceableParserUntyped>())
        {
            if (found.ReplaceableChild is not IMultiParser <TInput, TOutput> parser)
            {
                continue;
            }
            var replacement = transform(parser);
            if (replacement == null || ReferenceEquals(replacement, parser))
            {
                continue;
            }
            var result = found.SetParser(replacement);
            results.Add(result);
        }

        return(new MultiReplaceResult(results));
    }
        public void Replace_Transform_Fail_ReplacementNull()
        {
            var needle   = Fail <char>().Replaceable().Named("needle");
            var haystack = (Any(), Any(), Any(), needle).First();
            var result   = FindParserVisitor.Replace <char, char>(haystack, _ => false, null);

            result.Success.Should().BeFalse();
        }
        public void Replace_Transform_Fail_PredicateNull()
        {
            var needle   = Fail <char>().Replaceable().Named("needle");
            var haystack = (Any(), Any(), Any(), needle).First();
            var result   = FindParserVisitor.Replace <char, char>(haystack, (Func <IReplaceableParserUntyped, bool>)null, _ => needle);

            result.Success.Should().BeFalse();
        }
        public void Named_Test()
        {
            var needle   = Fail <char>().Named("needle");
            var haystack = (Any(), Any(), Any(), needle).First();
            var result   = FindParserVisitor.Named(haystack, "needle");

            result.Success.Should().BeTrue();
            result.Value.Should().BeSameAs(needle);
        }
        public void OfType_Test()
        {
            var needle   = Fail <char>().Named("needle");
            var haystack = (Any(), Any(), Any(), needle).First();
            var result   = FindParserVisitor.OfType <FailParser <char, char> >(haystack);

            result.Count.Should().Be(1);
            result[0].Should().BeSameAs(needle);
        }
Ejemplo n.º 6
0
    /// <summary>
    /// Search for all parsers of the given type. Returns all results.
    /// </summary>
    /// <typeparam name="TParser"></typeparam>
    /// <param name="root"></param>
    /// <returns></returns>
    public static IReadOnlyList <TParser> OfType <TParser>(IParser root)
        where TParser : IParser
    {
        Assert.ArgumentNotNull(root, nameof(root));
        var visitor = new FindParserVisitor();
        var state   = new State(p => p is TParser, false);

        visitor.Visit(root, state);
        return(state.Found.Cast <TParser>().ToList());
    }
Ejemplo n.º 7
0
    public static IOption <IParser> FindSingle(IParser root, Func <IParser, bool> predicate)
    {
        Assert.ArgumentNotNull(root, nameof(root));
        Assert.ArgumentNotNull(predicate, nameof(predicate));
        var visitor = new FindParserVisitor();
        var state   = new State(predicate, true);

        visitor.Visit(root, state);
        if (state.Found.Count > 0)
        {
            return(new SuccessOption <IParser>(state.Found.First()));
        }
        return(FailureOption <IParser> .Instance);
    }
        public void ReplaceMulti_ByName()
        {
            var fail     = FailMulti <char>();
            var needle   = FailMulti <char>().Replaceable().Named("needle");
            var success  = ProduceMulti(() => new[] { 'X' });
            var haystack = needle;

            var parseResult = haystack.Parse("X");

            parseResult.Success.Should().BeFalse();

            var result = FindParserVisitor.ReplaceMulti <char, char>(haystack, "needle", x => success);

            result.Success.Should().BeTrue();

            parseResult = haystack.Parse("X");
            parseResult.Success.Should().BeTrue();
            parseResult.Results[0].Value.Should().Be('X');
        }
        public void Replace_Single_ByName()
        {
            var fail     = Fail <char>();
            var needle   = Fail <char>().Replaceable().Named("needle");
            var success  = Any();
            var haystack = (fail, fail, fail, needle).First();

            var parseResult = haystack.Parse("X");

            parseResult.Success.Should().BeFalse();

            var result = FindParserVisitor.Replace(haystack, "needle", success);

            result.Success.Should().BeTrue();

            parseResult = haystack.Parse("X");
            parseResult.Success.Should().BeTrue();
            parseResult.Value.Should().Be('X');
        }
Ejemplo n.º 10
0
    /// <summary>
    /// Search for ReplaceableParsers matching a predicate and attempt to replace their contents with the
    /// replacement parser if it is found. The replacement parser must be non-null and of the correct
    /// type. Replaces all matching instances.
    /// </summary>
    /// <param name="root"></param>
    /// <param name="predicate"></param>
    /// <param name="replacement"></param>
    /// <returns></returns>
    public static MultiReplaceResult Replace(IParser root, Func <IReplaceableParserUntyped, bool> predicate, IParser replacement)
    {
        if (root == null || predicate == null || replacement == null)
        {
            return(MultiReplaceResult.Failure());
        }
        var visitor = new FindParserVisitor();
        var state   = new State(p => p is IReplaceableParserUntyped replaceable && predicate(replaceable), true);

        visitor.Visit(root, state);
        var results = new List <SingleReplaceResult>();

        foreach (var found in state.Found.Cast <IReplaceableParserUntyped>())
        {
            var result = found.SetParser(replacement);
            results.Add(result);
        }

        return(new MultiReplaceResult(results));
    }
Ejemplo n.º 11
0
 /// <summary>
 /// Given a parser graph, find a ReplaceableParser matching a predicate and attempt to
 /// transform the contents using the given transformation. The contents of the
 /// ReplaceableParser will be replaced with the transformed result if it is new and valid.
 /// </summary>
 /// <typeparam name="TInput"></typeparam>
 /// <typeparam name="TOutput"></typeparam>
 /// <param name="root"></param>
 /// <param name="name"></param>
 /// <param name="transform"></param>
 /// <returns></returns>
 public static MultiReplaceResult Replace <TInput, TOutput>(this IParser root, string name, Func <IMultiParser <TInput, TOutput>, IMultiParser <TInput, TOutput> > transform)
 => FindParserVisitor.ReplaceMulti(root, name, transform);
Ejemplo n.º 12
0
 /// <summary>
 /// Given a parser tree, find a ReplaceableParser with the given name and replace the child
 /// parser with the given replacement parser.
 /// </summary>
 /// <param name="root"></param>
 /// <param name="name"></param>
 /// <param name="replacement"></param>
 /// <returns></returns>
 public static MultiReplaceResult Replace(this IParser root, string name, IParser replacement)
 => FindParserVisitor.Replace(root, name, replacement);
Ejemplo n.º 13
0
 /// <summary>
 /// Given a parser tree, find a ReplaceableParsers matching a predicate and attempt to transform
 /// the contents using the given transformation. The contents of the ReplaceableParser will be
 /// replaced with the transformed result if it is new and valid.
 /// </summary>
 /// <typeparam name="TInput"></typeparam>
 /// <typeparam name="TOutput"></typeparam>
 /// <param name="root"></param>
 /// <param name="predicate"></param>
 /// <param name="transform"></param>
 /// <returns></returns>
 public static MultiReplaceResult Replace <TInput, TOutput>(this IParser root, Func <IParser, bool> predicate, Func <IParser <TInput, TOutput>, IParser <TInput, TOutput> > transform)
 => FindParserVisitor.Replace(root, predicate, transform);
Ejemplo n.º 14
0
 /// <summary>
 /// Given a parser tree, replace all children of ReplaceableParsers matching the given
 /// predicate with the provided replacement parser. Returns information about which
 /// instances were replaced.
 /// </summary>
 /// <param name="root"></param>
 /// <param name="predicate"></param>
 /// <param name="replacement"></param>
 /// <returns></returns>
 public static MultiReplaceResult Replace(this IParser root, Func <IParser, bool> predicate, IParser replacement)
 => FindParserVisitor.Replace(root, predicate, replacement);
Ejemplo n.º 15
0
 /// <summary>
 /// Recurse the tree searching for a parser with the given name. Returns a result with the
 /// parser if found, a failure flag otherwise.
 /// </summary>
 /// <param name="root"></param>
 /// <param name="name"></param>
 /// <returns></returns>
 public static IOption <IParser> FindNamed(this IParser root, string name) => FindParserVisitor.Named(root, name);
Ejemplo n.º 16
0
 /// <summary>
 /// Recurse the tree searching for a parser with the given id value. Returns a result with the
 /// parser if found, a failure otherwise.
 /// </summary>
 /// <param name="root"></param>
 /// <param name="id"></param>
 /// <returns></returns>
 public static IOption <IParser> Find(this IParser root, int id) => FindParserVisitor.ById(root, id);