/** * Adds a new transition * @param condition * @param to */ void addTransition(Range condition, DFAState<T> to) { Transition<DFAState<T>> t = new Transition<>(condition, this, to); t = transitions.put(t.getCondition(), t); assert t == null; edges.add(to); to.inStates.add(this); } /**
public void dump(Appendable p) throws IOException { for (NFAState<T> s : this) { for (Set<Transition<NFAState<T>>> set : s.getTransitions()) { for (Transition<NFAState<T>> t : set) p.append(s+"-"+t.getCondition()+">"+t.getTo()).append('\n'); } } }
/** * Returns true if set only has one epsilon transition. * @param set * @return */ public static boolean isSingleEpsilonOnly(Set<Transition<NFAState>> set) { if (set.size() != 1) { return false; } for (Transition<NFAState> tr : set) { if (tr.isEpsilon()) { return true; } } return false; } /**
set.add(state); Transition<DFAState<T>> tr = state.getTransitions().iterator().next(); Range condition = tr.getCondition(); int repeat = 1; DFAState<T> to = tr.getTo(); while (true) condition.equals(totr.getCondition()) && !set.contains(totr.getTo()) to = totr.getTo(); tr.setTo(to); tr.setRepeat(repeat); set.remove(state); set.remove(to);
/** * Returns next DFAState<T> for given condition or null if no transition exist * @param condition * @return */ public DFAState<T> transit(Range condition) { Transition<DFAState<T>> t = transitions.get(condition); if (t != null) { return t.getTo(); } return null; } /**
Range range = tr.getCondition(); DFAState to = s.transit(range); tload("reader"); if (first.getRepeat() > 1) tconst(first.getRepeat()); tstore("index"); String back = s.toString()+"-repeat"; tload("cc"); iflt("eof"); Range range = first.getCondition(); DFAState to = s.transit(range); compile(range, "error", !ti.hasNext()); Range range = tr.getCondition(); DFAState to = s.transit(range); String next = s.toString()+"-"+range+">"+to.toString(); for (Transition tr : s.getTransitions()) Range range = tr.getCondition(); if (range.getFrom() >= 0) Range range = tr.getCondition(); DFAState<T> to = s.transit(range); String target = s.toString()+"-"+range+">"+to.toString();
/** * Return true if one of transition ranges is a boundary match. * @return */ public boolean hasBoundaryMatches() { for (Transition<DFAState<T>> t : transitions.values()) { Range range = t.getCondition(); if (range.getFrom() < 0) { return true; } } return false; } /**
/** * Adds a epsilon transition * @param to */ public void addEpsilon(NFAState<T> to) { Transition<NFAState<T>> t = new Transition<>(this, to); Set<Transition<NFAState<T>>> set = transitions.get(null); if (set == null) { set = new HashSet<>(); transitions.put(null, set); } set.add(t); edges.add(to); to.inStates.add(this); } /**
void removeTransitionsFromAcceptImmediatelyStates() { if (acceptImmediately) { for (Transition<DFAState<T>> tr : transitions.values()) { DFAState<T> to = tr.getTo(); edges.remove(to); to.inStates.remove(this); } transitions.clear(); } }
/** * Calculates a value of how selective transitions are from this state. * Returns 1 if all ranges accept exactly one character. Greater number * means less selectivity * @return */ public int getTransitionSelectivity() { int count = 0; for (Transition<DFAState<T>> t : transitions.values()) { Range range = t.getCondition(); count += range.getTo()-range.getFrom(); } return count/transitions.size(); } /**
public void dump(PrintStream p) { for (DFAState<T> s : this) { for (Transition<DFAState<T>> t : s.getTransitions()) { p.println(stateDump(s)+"-"+t.getCondition()+">"+stateDump(t.getTo())); } } }
/** * Returns true if this state is not accepting and doesn't have any outbound * transitions. * @param nfaSet * @return */ boolean isDeadEnd(Set<NFAState<T>> nfaSet) { for (Set<Transition<NFAState<T>>> set : transitions.values()) { for (Transition<NFAState<T>> t : set) { if (!nfaSet.contains(t.getTo())) { return false; } } } return true; } /**
/** * Adds a transition * @param condition * @param to * @return */ public Transition<NFAState<T>> addTransition(Range condition, NFAState<T> to) { Transition<NFAState<T>> t = new Transition<>(condition, this, to); Set<Transition<NFAState<T>>> set = transitions.get(t.getCondition()); if (set == null) { set = new HashSet<>(); transitions.put(t.getCondition(), set); } set.add(t); edges.add(to); to.inStates.add(this); return t; } /**
for (Transition<NFAState> tr : firstOfFixedEnder) rs4.add(tr.getCondition());
/** * Optimizes transition by merging ranges */ void optimizeTransitions() { HashMap<DFAState<T>,RangeSet> hml = new HashMap<>(); for (Transition<DFAState<T>> t : transitions.values()) { RangeSet rs = hml.get(t.getTo()); if (rs == null) { rs = new RangeSet(); hml.put(t.getTo(), rs); } rs.add(t.getCondition()); } transitions.clear(); for (DFAState<T> dfa : hml.keySet()) { RangeSet rs = RangeSet.merge(hml.get(dfa)); for (Range r : rs) { addTransition(r, dfa); } } } /**
/** * Returns a set of NFAState<T>s to where a non epsilon transition exists * @return */ public Set<NFAState<T>> getNonEpsilonDestinations() { Set<NFAState<T>> set = new HashSet<>(); for (Range range : transitions.keySet()) { if (range != null) { Set<Transition<NFAState<T>>> set2 = transitions.get(range); for (Transition<NFAState<T>> tr : set2) { set.add(tr.getTo()); } } } return set; } public void removeAllNonEpsilonConditionsTo(NFAState<T> state)
/** * Removes transition to states that doesn't contain any outbound transition * and that are not accepting states */ void removeDeadEndTransitions() { Iterator<Range> it = transitions.keySet().iterator(); while (it.hasNext()) { Range r = it.next(); if (transitions.get(r).getTo().isDeadEnd()) { it.remove(); } } } /**
if (!indexOf.containsKey(t.getTo())) prefix.addLast(t.getCondition()); findSkip(t.getTo(),indexOf, stack, prefix); prefix.removeLast(); indexOf.put(state, Math.min(indexOf.get(state), indexOf.get(t.getTo())));
/** * Returns next DFAState<T> for given input or null if no transition exist * @param input * @return */ public DFAState<T> transit(int input) { for (Map.Entry<Range, Transition<DFAState<T>>> e : transitions.entrySet()) { Range r = e.getKey(); if (r.accept(input)) { return e.getValue().getTo(); } } return null; } /**