public <S, RESULT> List<RESULT> backtrack(Nfa<S> nfa, RESULT initial, BacktrackHandler<S, RESULT> handler) { Stack<BacktrackingItem<RESULT, S>> trace = new Stack<NfaUtil.BacktrackingItem<RESULT, S>>(); trace.push(new BacktrackingItem<RESULT, S>(initial, Collections.singleton(nfa.getStart()))); S stopState = nfa.getStop(); ROOT: while (!trace.isEmpty()) { BacktrackingItem<RESULT, S> item = trace.peek(); while (item.followers.hasNext()) { S nextState = item.followers.next(); RESULT nextResult = handler.handle(nextState, item.result); if (nextResult != null) { Iterable<S> followers = nfa.getFollowers(nextState); followers = handler.sortFollowers(nextResult, followers); trace.push(new BacktrackingItem<RESULT, S>(nextResult, followers)); if (stopState == nextState && handler.isSolution(nextResult)) { List<RESULT> result = Lists.newArrayList(); for (BacktrackingItem<RESULT, S> t : trace) result.add(t.result); return result; } continue ROOT; } } trace.pop(); } return null; }
public <S, RESULT> List<RESULT> backtrack(Nfa<S> nfa, RESULT initial, BacktrackHandler<S, RESULT> handler) { Stack<BacktrackingItem<RESULT, S>> trace = new Stack<NfaUtil.BacktrackingItem<RESULT, S>>(); trace.push(new BacktrackingItem<RESULT, S>(initial, Collections.singleton(nfa.getStart()))); S stopState = nfa.getStop(); ROOT: while (!trace.isEmpty()) { BacktrackingItem<RESULT, S> item = trace.peek(); while (item.followers.hasNext()) { S nextState = item.followers.next(); RESULT nextResult = handler.handle(nextState, item.result); if (nextResult != null) { Iterable<S> followers = nfa.getFollowers(nextState); followers = handler.sortFollowers(nextResult, followers); trace.push(new BacktrackingItem<RESULT, S>(nextResult, followers)); if (stopState == nextState && handler.isSolution(nextResult)) { List<RESULT> result = Lists.newArrayList(); for (BacktrackingItem<RESULT, S> t : trace) result.add(t.result); return result; } continue ROOT; } } trace.pop(); } return null; }