package pl.edu.amu.wmi.daut.base; import java.util.List; import java.util.LinkedList; /** * Klasa tworzy niedeterministyczny automat zgodnie z algorytmem Thompsona. */ public class NondeterministicAutomatonByThompsonApproach implements Acceptor { /** * Publiczny konstruktor. */ public NondeterministicAutomatonByThompsonApproach(AutomatonSpecification specification) { automaton = specification; } @Override public boolean accepts(final String text) { accept = false; int i = 0; int limit = text.length(); boolean added; currentStates = new LinkedList<State>(); List<State> temporaryStates = new LinkedList<State>(); List<State> pStates = new LinkedList<State>(); currentStates.add(automaton.getInitialState()); do { do { added = false; for (State someState : currentStates) { List<State> epsilonStates = new LinkedList<State>(epsilonClosure(someState)); for (State eState : epsilonStates) { if (!currentStates.contains(eState) && !pStates.contains(eState)) { pStates.add(eState); added = true; } } } currentStates.addAll(pStates); pStates.clear(); } while (added); if (limit != 0 && i != limit) { for (State someState : currentStates) { List<OutgoingTransition> someStateTransitions = new LinkedList<OutgoingTransition>( automaton.allOutgoingTransitions(someState)); for (OutgoingTransition transition : someStateTransitions) { if (transition.getTransitionLabel().isContextual()) { temporaryStates.addAll( automaton.getEpsilonClosureWithContext( someState, text, i)); } else if (transition.getTransitionLabel().canAcceptCharacter( text.charAt(i)) && !temporaryStates.contains( transition.getTargetState())) { temporaryStates.add(transition.getTargetState()); } } } currentStates.clear(); currentStates.addAll(temporaryStates); temporaryStates.clear(); } i++; } while (i <= limit); for (State someState : currentStates) { if (automaton.isFinal(someState)) { accept = true; } } return accept; } protected List<State> epsilonClosure(State state) { List<State> epsilonStates = new LinkedList<State>(); List<State> temporaryStates = new LinkedList<State>(); List<State> pStates = new LinkedList<State>(); boolean added; epsilonStates.add(state); do { added = false; for (State someState : epsilonStates) { List<OutgoingTransition> someStateTransitions = new LinkedList<OutgoingTransition>( automaton.allOutgoingTransitions(someState)); for (OutgoingTransition transition : someStateTransitions) { if (transition.getTransitionLabel().canBeEpsilon() && !temporaryStates.contains(transition.getTargetState())) { temporaryStates.add(transition.getTargetState()); } } for (State tState : temporaryStates) { if (!epsilonStates.contains(tState) && !pStates.contains(tState)) { pStates.add(tState); added = true; } } temporaryStates.clear(); } epsilonStates.addAll(pStates); pStates.clear(); } while (added); return epsilonStates; } protected AutomatonSpecification getSpecification() { return automaton; } private List<State> currentStates; private AutomatonSpecification automaton; private boolean accept; };