/*
* 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 gui.action;
import gui.environment.AutomatonEnvironment;
import gui.environment.EnvironmentFrame;
import gui.environment.Universe;
import gui.grammar.automata.ConvertController;
import gui.grammar.automata.ConvertPane;
import gui.grammar.automata.PDAConvertController;
import gui.viewer.SelectionDrawer;
import gui.viewer.ZoomPane;
import java.awt.BorderLayout;
import java.util.HashSet;
import java.util.Iterator;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
import automata.Automaton;
import automata.State;
import automata.Transition;
import automata.pda.PDAToCFGConverter;
import automata.pda.PDATransition;
import automata.pda.PushdownAutomaton;
/**
* This action handles the conversion of an PDA to a context free grammar.
*
* @author Thomas Finley
*/
public class ConvertPDAToGrammarAction extends ConvertAutomatonToGrammarAction {
/**
* Instantiates a new ConvertFSAToGrammarAction
.
*
* @param environment
* the environment
*/
public ConvertPDAToGrammarAction(AutomatonEnvironment environment) {
super(environment);
}
/**
* Checks the PDA to make sure it's ready to be converted.
*/
protected boolean checkAutomaton() {
EnvironmentFrame frame = Universe.frameForEnvironment(getEnvironment());
JPanel messagePanel = new JPanel(new BorderLayout());
SelectionDrawer drawer = new SelectionDrawer(getAutomaton());
JLabel messageLabel = new JLabel();
ZoomPane zoom = new ZoomPane(drawer);
JPanel tempPanel = new JPanel(new BorderLayout());
tempPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
zoom.setPreferredSize(new java.awt.Dimension(300, 200));
tempPanel.add(zoom, BorderLayout.CENTER);
messagePanel.add(tempPanel, BorderLayout.CENTER);
messagePanel.add(messageLabel, BorderLayout.SOUTH);
// Check the final states.
State[] finalStates = getAutomaton().getFinalStates();
if (finalStates.length != 1) {
JOptionPane.showMessageDialog(frame,
"There must be exactly one final state!",
"Final State Error", JOptionPane.ERROR_MESSAGE);
return false;
}
// Are all transitions to the final state okay?
Transition[] toFinal = getAutomaton().getTransitionsToState(
finalStates[0]);
HashSet bad = new HashSet();
for (int i = 0; i < toFinal.length; i++) {
PDATransition t = (PDATransition) toFinal[i];
if (!t.getStringToPop().equals("Z"))
bad.add(t);
}
if (bad.size() != 0) {
drawer.clearSelected();
Iterator it = bad.iterator();
while (it.hasNext())
drawer.addSelected((Transition) it.next());
messageLabel.setText("Transitions to final must pop only 'Z'.");
JOptionPane.showMessageDialog(frame, messagePanel,
"Final Transitions Error", JOptionPane.ERROR_MESSAGE);
return false;
}
// Are the transitions okay?
Transition[] transitions = getAutomaton().getTransitions();
bad.clear();
for (int i = 0; i < transitions.length; i++) {
PDATransition t = (PDATransition) transitions[i];
if (// t.getInputToRead().length() != 1 ||
t.getStringToPop().length() != 1
|| (t.getStringToPush().length() != 2 && t
.getStringToPush().length() != 0))
bad.add(t);
}
if (bad.size() != 0) {
drawer.clearSelected();
Iterator it = bad.iterator();
while (it.hasNext())
drawer.addSelected((Transition) it.next());
messageLabel.setText("Transitions must pop 1 and push 0 or 2.");
JOptionPane.showMessageDialog(frame, messagePanel,
"Transitions Error", JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
/**
* This object is only applicable to pushdown automatons.
*
* @param object
* the object to test
* @return true
if the object is a pushdown automaton, false
* otherwise
*/
public static boolean isApplicable(Object object) {
return object instanceof PushdownAutomaton;
}
/**
* Initializes the convert controller.
*
* @param pane
* the convert pane that holds the automaton pane and the grammar
* table
* @param drawer
* the selection drawer of the new view
* @param automaton
* the automaton that's being converted; note that this will not
* be the exact object returned by getAutomaton
* since a clone is made
* @return the convert controller to handle the conversion of the automaton
* to a grammar
*/
protected ConvertController initializeController(ConvertPane pane,
SelectionDrawer drawer, Automaton automaton) {
return new PDAConvertController(pane, drawer,
(PushdownAutomaton) automaton);
}
/** The environment this action is part of. */
private AutomatonEnvironment environment;
/** The automaton to convert. */
private PushdownAutomaton automaton;
/** The grammar converter. */
private PDAToCFGConverter converter = new PDAToCFGConverter();
}