/** Create a new instance. */ static Matcher create(List<Matcher> matchers) { return create(matchers.toArray(new Matcher[] {})); }
@Override public Matcher mergeNext(Matcher after) { if (after instanceof TrueMatcher) { return this; } List<Matcher> ms = new ArrayList<>(); for (Matcher m : matchers) { ms.add(SeqMatcher.create(m, after)); } return OrMatcher.create(ms); }
@Override public Matcher rewriteEnd(Function<Matcher, Matcher> f) { List<Matcher> ms = new ArrayList<>(); for (int i = 0; i < matchers.length - 1; ++i) { ms.add(matchers[i]); } ms.add(matchers[matchers.length - 1].rewriteEnd(f)); return f.apply(SeqMatcher.create(ms)); }
@Override public Matcher mergeNext(Matcher after) { if (after instanceof TrueMatcher) { return this; } Matcher m = (next instanceof TrueMatcher) ? after : SeqMatcher.create(next, after); return new ZeroOrMoreMatcher(repeated, m); }
@Override public Matcher mergeNext(Matcher after) { if (after instanceof TrueMatcher) { return this; } List<Matcher> ms = new ArrayList<>(); for (Matcher m : matchers) { ms.add(SeqMatcher.create(m, after)); } return OrMatcher.create(ms); }
@Override public Matcher mergeNext(Matcher after) { if (after instanceof TrueMatcher) { return this; } Matcher m = (next instanceof TrueMatcher) ? after : SeqMatcher.create(next, after); return new ZeroOrMoreMatcher(repeated, m); }
@Override public Matcher rewrite(Function<Matcher, Matcher> f) { List<Matcher> ms = new ArrayList<>(); for (Matcher m : matchers) { ms.add(m.rewrite(f)); } return f.apply(SeqMatcher.create(ms)); }
@Override public Matcher mergeNext(Matcher after) { if (after instanceof TrueMatcher) { return this; } Matcher m = (next instanceof TrueMatcher) ? after : SeqMatcher.create(next, after); return new IndexOfMatcher(pattern, m); }
@Override public Matcher rewrite(Function<Matcher, Matcher> f) { List<Matcher> ms = new ArrayList<>(); for (Matcher m : matchers) { ms.add(m.rewrite(f)); } return f.apply(SeqMatcher.create(ms)); }
@Override public Matcher mergeNext(Matcher after) { if (after instanceof TrueMatcher) { return this; } Matcher m = (next instanceof TrueMatcher) ? after : SeqMatcher.create(next, after); return new IndexOfMatcher(pattern, m); }
/** * Returns all but the first matcher from a sequence or True if there is only a single * matcher in the sequence. */ static Matcher tail(Matcher matcher) { if (matcher instanceof SeqMatcher) { List<Matcher> ms = matcher.<SeqMatcher>as().matchers(); return SeqMatcher.create(ms.subList(1, ms.size())); } else { return TrueMatcher.INSTANCE; } }
@Test public void combineAdjacentStart() { Matcher input = SeqMatcher.create( StartMatcher.INSTANCE, StartMatcher.INSTANCE, StartMatcher.INSTANCE, StartMatcher.INSTANCE, AnyMatcher.INSTANCE ); Matcher expected = SeqMatcher.create(StartMatcher.INSTANCE, AnyMatcher.INSTANCE); Assertions.assertEquals(expected, Optimizer.combineAdjacentStart(input)); }
@Test public void removeMatchAnyFollowedByStart() { Matcher input = new ZeroOrMoreMatcher(AnyMatcher.INSTANCE, SeqMatcher.create( StartMatcher.INSTANCE, AnyMatcher.INSTANCE )); Matcher expected = SeqMatcher.create(StartMatcher.INSTANCE, AnyMatcher.INSTANCE); Assertions.assertEquals(expected, Optimizer.removeMatchAnyFollowedByStart(input)); }
@Test public void sequenceWithFalseIsFalse() { Matcher input = SeqMatcher.create( AnyMatcher.INSTANCE, FalseMatcher.INSTANCE, AnyMatcher.INSTANCE ); Matcher expected = FalseMatcher.INSTANCE; Assertions.assertEquals(expected, Optimizer.sequenceWithFalseIsFalse(input)); }
@Test public void sequenceWithStuffAfterEndIsFalse() { Matcher input = SeqMatcher.create( AnyMatcher.INSTANCE, EndMatcher.INSTANCE, AnyMatcher.INSTANCE ); Matcher expected = FalseMatcher.INSTANCE; Assertions.assertEquals(expected, Optimizer.sequenceWithStuffAfterEndIsFalse(input)); }
@Test public void removeStartFollowedByMatchAny() { Matcher input = SeqMatcher.create( StartMatcher.INSTANCE, new ZeroOrMoreMatcher(AnyMatcher.INSTANCE, AnyMatcher.INSTANCE) ); Matcher expected = new ZeroOrMoreMatcher(AnyMatcher.INSTANCE, AnyMatcher.INSTANCE); Assertions.assertEquals(expected, Optimizer.removeStartFollowedByMatchAny(input)); }
@Test public void optimizeOptionValue() { PatternMatcher actual = PatternMatcher.compile("^a?a"); PatternMatcher expected = SeqMatcher.create( new StartsWithMatcher("a"), OrMatcher.create(new CharSeqMatcher("a"), TrueMatcher.INSTANCE) ); Assertions.assertEquals(expected, actual); }
@Test public void optimizeEndsWithPattern() { PatternMatcher actual = PatternMatcher.compile(".*foo.bar$"); PatternMatcher expected = new IndexOfMatcher( "foo", SeqMatcher.create( AnyMatcher.INSTANCE, new CharSeqMatcher("bar"), EndMatcher.INSTANCE ) ); Assertions.assertEquals(expected, actual); }
@Test public void optimizeOrPrefix() { PatternMatcher actual = PatternMatcher.compile("^(abc123|abc456)"); PatternMatcher expected = SeqMatcher.create( new StartsWithMatcher("abc"), new OrMatcher(new CharSeqMatcher("123"), new CharSeqMatcher("456")) ); Assertions.assertEquals(expected, actual); }
@Test public void optimizeOrPrefixPattern() { PatternMatcher actual = PatternMatcher.compile("^abc.*foo$|^abc.*bar$|^abc.*baz$"); PatternMatcher expected = SeqMatcher.create( new StartsWithMatcher("abc"), new OrMatcher( new IndexOfMatcher("foo", EndMatcher.INSTANCE), new IndexOfMatcher("bar", EndMatcher.INSTANCE), new IndexOfMatcher("baz", EndMatcher.INSTANCE) ) ); Assertions.assertEquals(expected, actual); }