Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.pitest.sequence;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class SequenceQuery {
private final Partial token;
SequenceQuery(Partial token) {
this.token = token;
}
public SequenceQuery then(Match next) {
return then(new SequenceQuery<>(new Literal<>(next)));
}
public SequenceQuery then(SequenceQuery next) {
final Concat concat = new Concat<>(this.token, next.token);
return new SequenceQuery<>(concat);
}
public SequenceQuery or(SequenceQuery next) {
final Or or = new Or<>(this.token, next.token);
return new SequenceQuery<>(or);
}
public SequenceQuery thenAnyOf(SequenceQuery left,
SequenceQuery right) {
final Or or = new Or<>(left.token, right.token);
final Concat concat = new Concat<>(this.token, or);
return new SequenceQuery<>(concat);
}
public SequenceQuery zeroOrMore(SequenceQuery next) {
final Concat concat = new Concat<>(this.token, new Repeat<>(next.token));
return new SequenceQuery<>(concat);
}
public SequenceQuery oneOrMore(SequenceQuery next) {
final Concat concat = new Concat<>(this.token, new Plus<>(next.token));
return new SequenceQuery<>(concat);
}
public SequenceMatcher compile() {
return compile(QueryParams.params());
}
@SuppressWarnings("unchecked")
public SequenceMatcher compile(QueryParams params) {
return new NFASequenceMatcher(params.ignoring(),
this.token.make(EndMatch.MATCH), params.isDebug());
}
interface Partial {
State make(State andThen);
}
static class Literal implements Partial {
final Match< T> c;
Literal(Match< T> p) {
this.c = p;
}
@Override
public State make(State andThen) {
return new Consume<>(this.c, andThen);
}
}
static class Or implements Partial {
final Partial left;
final Partial right;
Or(Partial left, Partial right) {
this.left = left;
this.right = right;
}
@Override
public State make(State andThen) {
final State l = this.left.make(andThen);
final State r = this.right.make(andThen);
return new Split<>(l, r);
}
}
static class Concat implements Partial {
final Partial left;
final Partial right;
Concat(Partial left, Partial right) {
this.left = left;
this.right = right;
}
@Override
public State make(State andThen) {
return this.left.make(this.right.make(andThen));
}
}
static class Repeat implements Partial {
final Partial r;
Repeat(Partial r) {
this.r = r;
}
@Override
public State make(State andThen) {
final Split placeHolder = new Split<>(null, null);
final State right = this.r.make(placeHolder);
placeHolder.out1 = new Split<>(right, andThen);
return placeHolder;
}
}
static class Plus implements Partial {
final Partial r;
Plus(Partial r) {
this.r = r;
}
@Override
public State make(State andThen) {
final Concat concat = new Concat<>(this.r, new Repeat<>(this.r));
return concat.make(andThen);
}
}
}
class NFASequenceMatcher implements SequenceMatcher {
private final boolean debug;
private final Match ignore;
private final State start;
NFASequenceMatcher(Match ignore, State state, boolean debug) {
this.ignore = ignore;
this.start = state;
this.debug = debug;
}
@Override
public boolean matches(List sequence) {
return matches(sequence, Context.start(this.debug));
}
@Override
public boolean matches(List sequence, Context initialContext) {
Set> currentState = run(sequence, initialContext);
return currentState.stream()
.map(c -> c.state)
.anyMatch(s -> s != null && s == EndMatch.MATCH);
}
@Override
public List contextMatches(List sequence, Context initialContext) {
Set> currentState = run(sequence, initialContext);
return currentState.stream()
.filter(s -> s.state != null && s.state == EndMatch.MATCH)
.map(c -> c.context)
.collect(Collectors.toList());
}
private Set> run(List sequence, Context initialContext) {
Set> currentState = new HashSet<>();
addState(currentState, new StateContext<>(this.start, initialContext));
for (final T t : sequence) {
// only initial context used in ignore checks
if (this.ignore.test(initialContext, t).result()) {
continue;
}
final Set> nextStates = step(currentState, t);
currentState = nextStates;
}
return currentState;
}
private static void addState(Set> set, StateContext state) {
if (state.state instanceof Split) {
final Split split = (Split) state.state;
if (split.out1 != null) {
addState(set, new StateContext(split.out1, state.context));
}
if (split.out2 != null) {
addState(set, new StateContext(split.out2, state.context));
}
} else {
set.add(state);
}
}
private static Set> step(Set> currentState, T c) {
// adhoc testing suggests setting the initial HashSet size saves 15% of analysis
// execution time
final Set> nextStates = new HashSet<>(currentState.size());
for (final StateContext each : currentState) {
if (each.state instanceof Consume) {
final Consume consume = (Consume) each.state;
final Result result = consume.c.test(each.context, c);
if (result.result()) {
// note, context updated here
addState(nextStates, new StateContext<>(consume.out, result.context()));
}
}
}
return nextStates;
}
}
interface State {
}
class Consume implements State {
final Match c;
final State out;
Consume(Match c, State out) {
this.c = c;
this.out = out;
}
}
class Split implements State {
State out1;
final State out2;
Split(State out1, State out2) {
this.out1 = out1;
this.out2 = out2;
}
}
@SuppressWarnings("rawtypes")
enum EndMatch implements State {
MATCH
}