/* * 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.grammar.automata; import automata.State; import automata.Transition; import automata.pda.PDAToCFGConverter; import automata.pda.PushdownAutomaton; import grammar.Grammar; import grammar.Production; import grammar.cfg.ContextFreeGrammar; import gui.viewer.SelectionDrawer; import java.util.*; /** * This controls the conversion of a push down automaton to a context free * grammar. * * @author Thomas Finley */ public class PDAConvertController extends ConvertController { /** * Instantiates a PDAConvertController for an automaton. * * @param pane * the convert pane that holds the automaton pane and the grammar * table * @param drawer * the selection drawer where the automaton is made * @param automaton * the automaton to build the PDAConvertController * for */ public PDAConvertController(ConvertPane pane, SelectionDrawer drawer, PushdownAutomaton automaton) { super(pane, drawer, automaton); converter = new PDAToCFGConverter(); converter.initializeConverter(); fillMap(); } /** * Returns the productions for a particular state. This method will only be * called once. * * @param state * the state to get the productions for * @return an array containing the productions that correspond to a * particular state */ protected Production[] getProductions(State state) { return new Production[0]; } /** * Returns the productions for a particular transition. This method will * only be called once. * * @param transition * the transition to get the productions for * @return an array containing the productions that correspond to a * particular transition */ protected Production[] getProductions(Transition transition) { return (Production[]) converter.createProductionsForTransition( transition, getAutomaton()).toArray(new Production[0]); } /** * Returns the grammar that's the result of this conversion. * * @return the grammar that's the result of this conversion * @throws GrammarCreationException * if there are not enough variables to uniquely identify every * variable here */ protected Grammar getGrammar() { int oldNumProductions = getModel().getProductions().length; converter.purgeProductions(getAutomaton(), getModel()); if (oldNumProductions != getModel().getProductions().length && converter.numberVariables() > 26) throw new GrammarCreationException( "Your list of rules has been trimmed, but there are still more variables than " + "can be uniquely represented."); else if (converter.numberVariables() > 26) throw new GrammarCreationException("There are more variables than can be uniquely represented."); else if (oldNumProductions != getModel().getProductions().length) javax.swing.JOptionPane.showMessageDialog(null, "Your list of rules has been trimmed."); int rows = getModel().getRowCount(); ContextFreeGrammar grammar = new ContextFreeGrammar(); grammar.setStartVariable("S"); ArrayList productions = new ArrayList(); for (int i = 0; i < rows; i++) { Production production = getModel().getProduction(i); if (production == null) continue; production = converter.getSimplifiedProduction(production); productions.add(production); } Collections.sort(productions, new Comparator() { public int compare(Object o1, Object o2) { Production p1 = (Production) o1, p2 = (Production) o2; if ("S".equals(p1.getLHS())) { if (p1.getLHS().equals(p2.getLHS())) return 0; else return -1; } if ("S".equals(p2.getLHS())) return 1; return p2.getLHS().compareTo(p1.getRHS()); } public boolean equals(Object o) { return false; } }); Iterator it = productions.iterator(); while (it.hasNext()) grammar.addProduction((Production) it.next()); return grammar; } /** The converter object from which we get the productions. */ private PDAToCFGConverter converter; }