public <S, P, R, D extends Pda<S, P>> D filterEdges( Pda<S, P> pda, Traverser<? super Pda<S, P>, S, R> traverser, PdaFactory<D, S, P, S> factory) { HashStack<TraversalItem<S, R>> trace = new HashStack<TraversalItem<S, R>>(); R previous = traverser.enter(pda, pda.getStart(), null); if (previous == null) return factory == null ? null : factory.create(pda.getStart(), pda.getStop()); Map<S, Integer> distances = new NfaUtil().distanceToFinalStateMap(pda); MappedComparator<S, Integer> distanceComp = new MappedComparator<S, Integer>(distances); trace.push(newItem(pda, distanceComp, distances, pda.getStart(), previous)); Multimap<S, S> edges = LinkedHashMultimap.create(); HashSet<S> states = Sets.newLinkedHashSet(); HashSet<Pair<S, R>> success = Sets.newLinkedHashSet(); states.add(pda.getStart()); states.add(pda.getStop()); ROOT: while (!trace.isEmpty()) { TraversalItem<S, R> current = trace.peek(); while (current.followers.hasNext()) { S next = current.followers.next(); R item = traverser.enter(pda, next, current.data); if (item != null) { if ((next == pda.getStop() && traverser.isSolution(item)) || success.contains(Tuples.create(next, item))) { S s = null; for (TraversalItem<S, R> i : trace) { if (s != null) edges.put(s, i.state); states.add(i.state); success.add(Tuples.create(i.state, i.data)); s = i.state; } edges.put(s, next); } else { if (trace.push(newItem(pda, distanceComp, distances, next, item))) continue ROOT; } } } trace.pop(); } if (factory == null) return null; D result = factory.create(pda.getStart(), pda.getStop()); Map<S, S> old2new = Maps.newLinkedHashMap(); old2new.put(pda.getStart(), result.getStart()); old2new.put(pda.getStop(), result.getStop()); for (S old : states) { if (old == pda.getStart() || old == pda.getStop()) continue; else if (pda.getPop(old) != null) old2new.put(old, factory.createPop(result, old)); else if (pda.getPush(old) != null) old2new.put(old, factory.createPush(result, old)); else old2new.put(old, factory.createState(result, old)); } for (S old : states) { List<S> followers = Lists.newArrayList(); for (S f : edges.get(old)) followers.add(old2new.get(f)); factory.setFollowers(result, old2new.get(old), followers); } return result; }
protected <S, P, T, D extends Pda<S, P>> S clone( S state, Pda<S, P> src, D target, Function<S, T> tokens, PdaFactory<D, S, P, T> fact, Identity<S> identity) { if (state == src.getStart()) return target.getStart(); if (state == src.getStop()) return target.getStop(); P push = src.getPush(state); if (push != null) return identity.get(fact.createPush(target, tokens.apply(state))); P pop = src.getPop(state); if (pop != null) return identity.get(fact.createPop(target, tokens.apply(state))); return identity.get(fact.createState(target, tokens.apply(state))); }
protected <S, P, E, T1, T2, D extends Pda<S, P>> void create( Cfg<E, T1> cfg, D pda, S state, E ele, Iterable<E> followerElements, FollowerFunction<E> ff, Function<E, T2> tokens, PdaFactory<D, S, P, ? super T2> fact, Map<E, S> states, Map<E, S> stops, Multimap<E, E> callers) { List<S> followerStates = Lists.newArrayList(); for (E fol : followerElements) { E e; if (fol == null) { E root = new ProductionUtil().getRoot(cfg, ele); if (root == cfg.getRoot()) followerStates.add(pda.getStop()); for (E c : callers.get(root)) { S s = stops.get(c); if (s == null) { s = fact.createPop(pda, tokens.apply(c)); stops.put(c, s); create(cfg, pda, s, c, ff.getFollowers(c), ff, tokens, fact, states, stops, callers); } followerStates.add(s); } } else if ((e = cfg.getCall(fol)) != null) { S s = states.get(fol); if (s == null) { s = fact.createPush(pda, tokens.apply(fol)); states.put(fol, s); create(cfg, pda, s, e, ff.getStarts(e), ff, tokens, fact, states, stops, callers); } followerStates.add(s); } else { S s = states.get(fol); if (s == null) { s = fact.createState(pda, tokens.apply(fol)); states.put(fol, s); create(cfg, pda, s, fol, ff.getFollowers(fol), ff, tokens, fact, states, stops, callers); } followerStates.add(s); } } fact.setFollowers(pda, state, followerStates); }