/** * Generates new states for all the old states in the provided FSM. Stores the newly created * states into the {@link #newStates} list, and populates the mapping between old state IDs and * new state IDs in {@link #oldToNewStates}. * * @param the {@link FSMPDA} from which the old states are obtained. */ protected void createNewStates(FSMPDA fsm) { LinkedList<StatePDA> oldStatesQueue = new LinkedList<StatePDA>(); oldStatesQueue.add(fsm.getInitialState()); while (oldStatesQueue.size() > 0) { StatePDA anOldState = oldStatesQueue.removeFirst(); if (oldToNewStates.containsKey(anOldState.getIndex())) { // state already converted } else { // new state required SPTBase.State newState = new SPTBase.State(); newStates.add(newState); oldToNewStates.put(anOldState.getIndex(), newStates.size() - 1); // queue all old states reachable from this state for (gate.fsm.Transition anOldTransition : anOldState.getTransitions()) { oldStatesQueue.add((StatePDA) anOldTransition.getTarget()); } // if state is final, set the rule value newState.rule = -1; if (anOldState.isFinal()) { RightHandSide rhs = anOldState.getAction(); for (int i = 0; i < rules.length; i++) { if (rules[i].getRHS() == rhs) { newState.rule = i; break; } } } } } }
/** * Parses the provided FSMPDA and converts the old transitions to new ones. The {@link #newStates} * list and the {@link #oldToNewStates} mapping should already be populated before this method is * called. * * @param fsm * @throws ResourceInstantiationException */ protected void createNewTransitions(FSMPDA fsm) throws ResourceInstantiationException { LinkedList<StatePDA> oldStatesQueue = new LinkedList<StatePDA>(); oldStatesQueue.add(fsm.getInitialState()); IntArrayList visitedOldStates = new IntArrayList(); while (oldStatesQueue.size() > 0) { StatePDA anOldState = oldStatesQueue.removeFirst(); if (visitedOldStates.contains(anOldState.getIndex())) { // state already processed -> nothing to do } else { if (!oldToNewStates.containsKey(anOldState.getIndex())) { throw new ResourceInstantiationException( "State mapping org.p4535992.mvc.error: " + "old state not associated with a new state!"); } SPTBase.State newState = newStates.get(oldToNewStates.get(anOldState.getIndex())); // now process all transitions List<SPTBase.Transition> newTransitions = new LinkedList<SPTBase.Transition>(); for (gate.fsm.Transition t : anOldState.getTransitions()) { TransitionPDA anOldTransition = (TransitionPDA) t; if (!visitedOldStates.contains(anOldTransition.getTarget().getIndex())) { oldStatesQueue.add((StatePDA) anOldTransition.getTarget()); } if (!oldToNewStates.containsKey(anOldTransition.getTarget().getIndex())) { throw new ResourceInstantiationException( "State mapping org.p4535992.mvc.error: " + "old target state not associated with a new state!"); } int newStateTarget = oldToNewStates.get(anOldTransition.getTarget().getIndex()); SPTBase.Transition newTransition = new SPTBase.Transition(); newTransitions.add(newTransition); newTransition.nextState = newStateTarget; newTransition.type = anOldTransition.getType(); if (newTransition.type != TransitionPDA.TYPE_CONSTRAINT) { continue; } Constraint[] oldConstraints = anOldTransition.getConstraints().getConstraints(); List<int[]> newConstraints = new ArrayList<int[]>(); for (int i = 0; i < oldConstraints.length; i++) { String annType = oldConstraints[i].getAnnotType(); int annTypeInt = annotationTypes.indexOf(annType); if (annTypeInt < 0) { annotationTypes.add(annType); annTypeInt = annotationTypes.size() - 1; } int[] newConstraint = new int[oldConstraints[i].getAttributeSeq().size() + 2]; newConstraints.add(newConstraint); newConstraint[0] = annTypeInt; newConstraint[1] = oldConstraints[i].isNegated() ? -1 : 0; int predId = 2; for (ConstraintPredicate oldPredicate : oldConstraints[i].getAttributeSeq()) { newConstraint[predId++] = convertPredicate(annType, oldPredicate); } } // now save the new constraints newTransition.constraints = new int[newConstraints.size()][]; newTransition.constraints = newConstraints.toArray(newTransition.constraints); } // convert the transitions list to an array newState.transitions = new SPTBase.Transition[newTransitions.size()]; newState.transitions = newTransitions.toArray(newState.transitions); // finally, mark the old state as visited. visitedOldStates.add(anOldState.getIndex()); } } }