/** * Creates an empty nfa * @param scope */ public NFA(Scope<NFAState<T>> scope) { this.scope = scope; first = new NFAState<>(scope); last = new NFAState<>(scope); first.addEpsilon(last); } /**
/** * Constructs a nfa containing two states which have transitions from first * to last * <p> * first -rs> last * @param scope * @param rs Range set containing the transition ranges. */ public NFA(Scope<NFAState<T>> scope, RangeSet rs) { this.scope = scope; first = new NFAState<>(scope); last = new NFAState<>(scope); first.addTransition(rs, last); } /**
/** * Creates a dfa state from all nfa states that can be reached from this state * with epsilon move. * @param scope * @return */ public Set<NFAState<T>> epsilonClosure(Scope<DFAState<T>> scope) { Set<NFAState<T>> set = new HashSet<>(); set.add(this); return epsilonClosure(scope, set); } /**
if (end.hasTransitions()) NFAState current = prev.prev(); while (current != null) if (current.hasTransitionTo(null, prev) && prev.hasTransitionTo(null, current)) Set<Transition<NFAState>> transitionSet = current.getSingleTransitionTo(prev); if (transitionSet != null) if (!NFAState.isSingleEpsilonOnly(transitionSet)) if (current.hasTransitionTo(null, prev)) current = prev.prev(); current = prev.prev(); if (!current.hasTransitionTo(null, prev) || !prev.hasTransitionTo(null, current)) RangeSet rs = current.getNonEpsilonConditionsTo(prev); if (rs.isEmpty()) RangeSet rs3 = s.getNonEpsilonConditions(); rs2.remove(rs3); s.addTransition(rs2, current); current.removeAllNonEpsilonConditionsTo(prev); RangeSet rs4 = new RangeSet();
public NFA<Integer> createNFA(Scope<NFAState<Integer>> scope) throws IOException { NFA<Integer> nfa = Regex.createNFA(scope, expression, getNumber(), options); NFAState<Integer> last = nfa.getLast(); last.setToken(getNumber()); last.setPriority(priority); if (Option.supports(options, Option.ACCEPT_IMMEDIATELY)) { last.setAcceptImmediately(true); } return nfa; }
/** * Creates a Nondeterministic finite automata from regular expression * @param expression * @param reducer Reducer marks the accepting state with unique identifier * @param ignoreCase * @return */ @Override public NFA<T> createNFA(Scope<NFAState<T>> scope, String expression, T reducer, Option... options) { Literal literal = new Literal(); NFA<T> nfa = parse(expression, scope, literal, options); if (Option.supports(options, Option.FIXED_ENDER)) { NFA.modifyFixedEnder(nfa); } NFAState<T> last = nfa.getLast(); last.setToken(reducer); if (literal.isLiteral()) { last.changePriority(1); } if (Option.supports(options, Option.ACCEPT_IMMEDIATELY)) { last.setAcceptImmediately(true); } return nfa; } @ParseMethod(start="regexp", features={SingleThread})
/** * Changes this nfa to be optional by adding epsilon from first to last. */ public void opt() { first.addEpsilon(last); }
/** * Returns a set of states that can be reached by epsilon transitions. * @param marked * @return */ private Set<NFAState<T>> epsilonTransitions(StateVisitSet<NFAState<T>> marked) { marked.add(this); Set<NFAState<T>> set = new HashSet<>(); for (NFAState<T> nfa : epsilonTransit()) { if (!marked.contains(nfa)) { set.add(nfa); set.addAll(nfa.epsilonTransitions(marked)); } } return set; } /**
operandStack.peek().getLast().setToken(reducer); return operandStack.pop();
/** * Adds a set of transitions * @param rs * @param to */ public void addTransition(RangeSet rs, NFAState<T> to) { for (Range c : rs) { addTransition(c, to); } edges.add(to); to.inStates.add(this); } /**
/** * Construct a new nfa by cloning the other. * @param scope * @param other */ public NFA(Scope<NFAState<T>> scope, NFA<T> other) { this.scope = scope; Map<NFAState<T>,NFAState<T>> map = new NumMap<>(); for (NFAState<T> s : other) { NFAState<T> to = map.get(s); if (to == null) { to = new NFAState(scope, s, map); map.put(s, to); } } first = map.get(other.first); last = map.get(other.last); } /**
/** * Constructs a dfa from using first nfa state as starting state. * @param scope * @return */ public DFA<T> constructDFA(Scope<DFAState<T>> scope) { return new DFA<>(first.constructDFA(scope), scope.count()); } /**
sb.append("-"+range+">"+t.getTo()); p = sb.length()-p; t.getTo().dump(p, sb, map, deque);
/** * Concatenates this to nfa by making epsilon move from this last to nfa first. * @param nfa */ public void concat(NFA<T> nfa) { last.addEpsilon(nfa.getFirst()); last = nfa.last; } /**
/** * Changes this nfa to be a Kleenes star by adding epsilon moves from first to * last and vice versa. Extra epsilon connected state is added at the end. * This is to prevent future epsilon moves from flowing backwards. E.g (ab*)? */ public void star() { last.addEpsilon(first); first.addEpsilon(last); NFAState<T> s = new NFAState<>(scope); last.addEpsilon(s); last = s; } /**
s.addEpsilon(result.getLast());
/** * Construct a new nfa state by cloning other state as well as all connected * states. * @param other * @param map */ NFAState(Scope<NFAState<T>> scope, NFAState<T> other, Map<NFAState<T>,NFAState<T>> map) { super(scope, other); map.put(other, this); for (Range r : other.transitions.keySet()) { Set<Transition<NFAState<T>>> s = other.transitions.get(r); for (Transition<NFAState<T>> t : s) { NFAState<T> to = map.get(t.getTo()); if (to == null) { to = new NFAState<>(scope, t.getTo(), map); } addTransition(r, to); } } } public boolean isAcceptImmediately()
Set<NFAState<T>> startSet = epsilonClosure(dfaScope); DFAState<T> startDfa = new DFAState<>(dfaScope, startSet); all.put(startSet, startDfa); if (!moveSet.isEmpty()) Set<NFAState<T>> newSet = epsilonClosure(dfaScope, moveSet); DFAState<T> ndfa = all.get(newSet); if (ndfa == null)
last = new NFAState<>(scope); nfa1.last.addEpsilon(last); first.addEpsilon(nfa2.getFirst()); nfa2.getLast().addEpsilon(last); last = new NFAState<>(scope); nfa2.last.addEpsilon(last); first.addEpsilon(nfa1.getFirst()); nfa1.getLast().addEpsilon(last); first = new NFAState<>(scope); last = new NFAState<>(scope); first.addEpsilon(nfa1.getFirst()); first.addEpsilon(nfa2.getFirst()); nfa1.getLast().addEpsilon(last); nfa2.getLast().addEpsilon(last);