/*
* JFLAP - Formal Languages and Automata Package
*
*
* Susan H. Rodger
* Computer Science Department
* Duke University
* August 27, 2009
* Copyright (c) 2002-2009
* All rights reserved.
* JFLAP is open source software. Please see the LICENSE for terms.
*
*/
package automata.fsa;
import java.util.ArrayList;
import java.util.HashSet;
import debug.EDebug;
import automata.Automaton;
import automata.ClosureTaker;
import automata.Configuration;
import automata.State;
import automata.Transition;
/**
* The FSA step with closure simulator object simulates the behavior of a finite
* state automaton. It takes an FSA object and an input string and runs the
* machine on the input. It simulates the machine's behavior by stepping one
* state at a time, then taking the closure of each state reached by one step of
* the machine to find out all possible configurations of the machine at any
* given point in the simulation.
*
* @author Ryan Cavalcante
*/
public class FSAStepWithClosureSimulator extends FSAStepByStateSimulator {
/**
* Creates an instance of StepWithClosureSimulator
*/
public FSAStepWithClosureSimulator(Automaton automaton) {
super(automaton);
}
/**
* Returns an array of FSAConfiguration objects that represent the possible
* initial configurations of the FSA, before any input has been processed,
* calculated by taking the closure of the initial state.
*
* @param input
* the input string.
*/
public Configuration[] getInitialConfigurations(String input) {
State init = myAutomaton.getInitialState();
State[] closure = ClosureTaker.getClosure(init, myAutomaton);
Configuration[] configs = new Configuration[closure.length];
for (int k = 0; k < closure.length; k++) {
configs[k] = new FSAConfiguration(closure[k], null, input, input);
}
return configs;
}
/**
* Simulates one step for a particular configuration, adding all possible
* configurations reachable in one step to set of possible configurations.
*
* @param config
* the configuration to simulate the one step on.
*/
public ArrayList stepConfiguration(Configuration config) {
ArrayList list = new ArrayList();
FSAConfiguration configuration = (FSAConfiguration) config;
/** get all information from configuration. */
String unprocessedInput = configuration.getUnprocessedInput();
String totalInput = configuration.getInput();
State currentState = configuration.getCurrentState();
Transition[] transitions = myAutomaton
.getTransitionsFromState(currentState);
for (int k = 0; k < transitions.length; k++) {
FSATransition transition = (FSATransition) transitions[k];
/** get all information from transition. */
String transLabel = transition.getLabel();
HashSet trange = new HashSet();
if (transLabel.contains("[")){
for(int i=transLabel.charAt(transLabel.indexOf("[")+1); i<=transLabel.charAt(transLabel.indexOf("[")+3); i++){
trange.add(Character.toString((char)i));
EDebug.print(Character.toString((char)i));
}
if (transLabel.length() > 0) {
for(String element : trange){
if (unprocessedInput.startsWith(element)) {
String input = "";
if (element.length() < unprocessedInput.length()) {
input = unprocessedInput.substring(element.length());
}
State toState = transition.getToState();
FSAConfiguration configurationToAdd = new FSAConfiguration(
toState, configuration, totalInput, input);
list.add(configurationToAdd);
}
}
}
}
else if (transLabel.length() > 0) {
if (unprocessedInput.startsWith(transLabel)) {
String input = "";
if (transLabel.length() < unprocessedInput.length()) {
input = unprocessedInput.substring(transLabel.length());
}
State toState = transition.getToState();
State[] closure = ClosureTaker.getClosure(toState,
myAutomaton);
for (int i = 0; i < closure.length; i++) {
FSAConfiguration configurationToAdd = new FSAConfiguration(
closure[i], configuration, totalInput, input);
list.add(configurationToAdd);
}
}
}
}
return list;
}
}