package de.unisiegen.gtitool.ui.logic; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Collections; import java.util.Timer; import java.util.TimerTask; import javax.swing.DefaultListModel; import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.TransferHandler; import de.unisiegen.gtitool.core.entities.DefaultNonterminalSymbol; import de.unisiegen.gtitool.core.entities.DefaultNonterminalSymbolSet; import de.unisiegen.gtitool.core.entities.DefaultProduction; import de.unisiegen.gtitool.core.entities.DefaultProductionWord; import de.unisiegen.gtitool.core.entities.DefaultTerminalSymbol; import de.unisiegen.gtitool.core.entities.DefaultTerminalSymbolSet; import de.unisiegen.gtitool.core.entities.NonterminalSymbol; import de.unisiegen.gtitool.core.entities.NonterminalSymbolSet; import de.unisiegen.gtitool.core.entities.Production; import de.unisiegen.gtitool.core.entities.ProductionWord; import de.unisiegen.gtitool.core.entities.ProductionWordMember; import de.unisiegen.gtitool.core.entities.TerminalSymbol; import de.unisiegen.gtitool.core.entities.TerminalSymbolSet; import de.unisiegen.gtitool.core.entities.listener.ModifyStatusChangedListener; import de.unisiegen.gtitool.core.exceptions.nonterminalsymbolset.NonterminalSymbolSetException; import de.unisiegen.gtitool.core.exceptions.terminalsymbolset.TerminalSymbolSetException; import de.unisiegen.gtitool.core.grammars.Grammar; import de.unisiegen.gtitool.core.grammars.cfg.CFG; import de.unisiegen.gtitool.core.grammars.cfg.DefaultCFG; import de.unisiegen.gtitool.core.parser.style.PrettyString; import de.unisiegen.gtitool.core.parser.style.PrettyToken; import de.unisiegen.gtitool.core.parser.style.Style; import de.unisiegen.gtitool.core.parser.style.renderer.PrettyStringListCellRenderer; import de.unisiegen.gtitool.core.util.ObjectPair; import de.unisiegen.gtitool.logger.Logger; import de.unisiegen.gtitool.ui.i18n.Messages; import de.unisiegen.gtitool.ui.logic.interfaces.LogicClass; import de.unisiegen.gtitool.ui.model.ConvertMachineTableColumnModel; import de.unisiegen.gtitool.ui.model.ConvertMachineTableModel; import de.unisiegen.gtitool.ui.model.DefaultGrammarModel; import de.unisiegen.gtitool.ui.model.GrammarColumnModel; import de.unisiegen.gtitool.ui.netbeans.ConvertGrammarDialogForm; import de.unisiegen.gtitool.ui.netbeans.ConvertMachineDialogForm; import de.unisiegen.gtitool.ui.netbeans.ConvertRegexToMachineDialogForm; import de.unisiegen.gtitool.ui.preferences.PreferenceManager; import de.unisiegen.gtitool.ui.swing.JGTIList; import de.unisiegen.gtitool.ui.swing.JGTITable; import de.unisiegen.gtitool.ui.swing.dnd.JGTIListModelRows; import de.unisiegen.gtitool.ui.swing.dnd.JGTIListTransferHandler; import de.unisiegen.gtitool.ui.utils.TextLoader; /** * The LogicClass for the RegexToMachine Converter * * @author Simon Meurer */ public class ConvertGrammarDialog implements LogicClass < ConvertGrammarDialogForm > { /** * Does the next step after a delay. * * @author Simon Meurer */ private final class AutoStepTimerTask extends TimerTask { /** * {@inheritDoc} * * @see TimerTask#run() */ @Override public final void run () { SwingUtilities.invokeLater ( new Runnable () { @SuppressWarnings ( "synthetic-access" ) public void run () { if ( ConvertGrammarDialog.this.endReached ) { handleStop (); } else { performNextStep (); } } } ); } } /** * The Type of the conversion of the {@link Grammar} */ public enum ConvertGrammarType { /** * The eliminate entity productions type */ ELIMINATE_ENTITY_PRODUCTIONS, /** * The eliminate epsilon productions type */ ELIMINATE_EPSILON_PRODUCTIONS, /** * The eliminate left recursion type */ ELIMINATE_LEFT_RECURSION, /** * The left factoring type */ LEFT_FACTORING; } /** * The {@link StepItem}. * * @author Simon Meurer */ private class StepItem { /** * The added epsilon {@link Production} */ private Production addedEpsilonProduction; /** * True if a {@link Production} was found */ private boolean foundProduction; /** * The current i */ private int iNow; /** * The current j */ private int jNow; /** * The current {@link CFG} */ private CFG oldCFG; /** * The current nonterminals as {@link DefaultListModel} */ private DefaultListModel oldNonterminalModel; /** * The old oldWorkingProductions */ private ArrayList < Production > oldWorkingProductions; /** * Allocates a new {@link StepItem}. * * @param oldCFG The current {@link CFG} * @param oldNonterminalModel The current nonterminals * @param i The current i * @param j The current j * @param addedEpsilonProduction The added epsilon {@link Production} * @param foundProduction True if new Production was found * @param oldWorkingProductions The old working productions */ public StepItem ( CFG oldCFG, DefaultListModel oldNonterminalModel, int i, int j, Production addedEpsilonProduction, boolean foundProduction, ArrayList < Production > oldWorkingProductions ) { this.oldCFG = oldCFG; this.oldNonterminalModel = oldNonterminalModel; this.iNow = i; this.jNow = j; this.addedEpsilonProduction = addedEpsilonProduction; this.foundProduction = foundProduction; this.oldWorkingProductions = oldWorkingProductions; } /** * Returns the addedEpsilonProduction. * * @return The addedEpsilonProduction. * @see #addedEpsilonProduction */ public Production getAddedEpsilonProduction () { return this.addedEpsilonProduction; } /** * Returns the iNow. * * @return The iNow. * @see #iNow */ public int getINow () { return this.iNow; } /** * Returns the jNow. * * @return The jNow. * @see #jNow */ public int getJNow () { return this.jNow; } /** * Returns the oldCFG. * * @return The oldCFG. * @see #oldCFG */ public CFG getOldCFG () { return this.oldCFG; } /** * Returns the oldNonterminalModel. * * @return The oldNonterminalModel. * @see #oldNonterminalModel */ public DefaultListModel getOldNonterminalModel () { return this.oldNonterminalModel; } /** * Returns the oldWorkingProductions. * * @return The oldWorkingProductions. * @see #oldWorkingProductions */ public ArrayList < Production > getWorkingProductions () { return this.oldWorkingProductions; } /** * Returns the foundProduction. * * @return The foundProduction. * @see #foundProduction */ public boolean isFoundProduction () { return this.foundProduction; } } /** * The {@link Logger} for this class. */ private static final Logger logger = Logger .getLogger ( ConvertGrammarDialog.class ); /** * The algorithm */ private String algorithm; /** * The algorithm window */ private TextWindow algorithmWindow; /** * The auto step {@link Timer}. */ private Timer autoStepTimer = null; /** * The {@link ConvertMachineTableModel}. */ private ConvertMachineTableModel convertMachineTableModel; /** * The {@link ConvertGrammarType} */ private ConvertGrammarType convertType; /** * Flag that indicates if the end is reached. */ private boolean endReached = false; /** * The entity {@link Production}s */ private ArrayList < Production > entityProductions; /** * The epsilon {@link Production}s */ private ArrayList < Production > epsilonProductions; /** * The {@link GrammarColumnModel}. */ private GrammarColumnModel grammarColumnModelConverted = new GrammarColumnModel (); /** * The {@link GrammarColumnModel}. */ private GrammarColumnModel grammarColumnModelOriginal = new GrammarColumnModel (); /** * The {@link ConvertRegexToMachineDialogForm} */ private ConvertGrammarDialogForm gui; /** * The variable i in the algorithm */ private int i = 1; /** * Flag indicates if entity productions are eliminated */ private boolean initialEliminateEntityProductionsDone = false; /** * Flag indicates if epsilon productions are eliminated */ private boolean initialEliminateEpsilonProductionsDone = false; /** * The initial nonterminal size */ private int initialNonterminalSize; /** * The variable j in the algorithm */ private int j = 1; /** * The {@link DefaultGrammarModel} for the converted {@link CFG} */ private DefaultGrammarModel modelConverted; /** * The {@link DefaultGrammarModel} for the original {@link CFG} */ private DefaultGrammarModel modelOriginal; /** * The {@link NonterminalSymbol}s of the converted {@link CFG} as List */ private DefaultListModel nonterminals = new DefaultListModel (); /** * The {@link GrammarPanel} */ private GrammarPanel panel; /** * The parent {@link JFrame} */ private JFrame parent; /** * The {@link StepItem} list. */ private ArrayList < StepItem > stepItemList = new ArrayList < StepItem > (); /** * The {@link ConvertMachineTableColumnModel}. */ private ConvertMachineTableColumnModel tableColumnModel = new ConvertMachineTableColumnModel (); /** * The working productions */ private ArrayList < Production > workingProductions; /** * Creates new from {@link ConvertGrammarDialog} * * @param parent The parent {@link JFrame} * @param panel The {@link RegexPanel} */ public ConvertGrammarDialog ( JFrame parent, GrammarPanel panel ) { this.parent = parent; this.panel = panel; } /** * Adds a outline comment. * * @param prettyString The {@link PrettyString} to add. */ private final void addOutlineComment ( PrettyString prettyString ) { this.convertMachineTableModel.addRow ( prettyString ); this.gui.jGTITableOutline.changeSelection ( this.convertMachineTableModel .getRowCount () - 1, ConvertMachineTableModel.OUTLINE_COLUMN, false, false ); } /** * Cancels the auto step timer. */ private final void cancelAutoStepTimer () { if ( this.autoStepTimer != null ) { this.autoStepTimer.cancel (); this.autoStepTimer = null; } } /** * Clones the converted {@link CFG} * * @return The cloned converted {@link CFG} */ private CFG cloneConverted () { NonterminalSymbol start = null; NonterminalSymbolSet nonterminalSet = new DefaultNonterminalSymbolSet (); for ( NonterminalSymbol s : this.modelConverted.getGrammar () .getNonterminalSymbolSet () ) { NonterminalSymbol c = new DefaultNonterminalSymbol ( s.getName () ); try { c.setHighlighted ( s.isHighlighted () ); nonterminalSet.add ( c ); } catch ( NonterminalSymbolSetException exc ) { exc.printStackTrace (); } if ( s.equals ( this.modelConverted.getGrammar ().getStartSymbol () ) ) { start = c; } } TerminalSymbolSet terminals = new DefaultTerminalSymbolSet (); for ( TerminalSymbol s : this.modelConverted.getGrammar () .getTerminalSymbolSet () ) { try { terminals.add ( new DefaultTerminalSymbol ( s.getName () ) ); } catch ( TerminalSymbolSetException exc ) { exc.printStackTrace (); } } CFG newCFG = new DefaultCFG ( nonterminalSet, terminals, start ); for ( Production p : this.modelConverted.getGrammar ().getProduction () ) { NonterminalSymbol nonterminal = null; for ( NonterminalSymbol s : nonterminalSet ) { if ( p.getNonterminalSymbol ().getName ().equals ( s.getName () ) ) { nonterminal = s; } } ProductionWord word = new DefaultProductionWord (); for ( ProductionWordMember m : p.getProductionWord () ) { for ( NonterminalSymbol n : nonterminalSet ) { if ( m.getName ().equals ( n.getName () ) ) { word.add ( n ); } } for ( TerminalSymbol t : terminals ) { if ( m.getName ().equals ( t.getName () ) ) { word.add ( t ); } } } Production newProd = new DefaultProduction ( nonterminal, word ); newProd.setHighlighted ( p.isHighlighted () ); newCFG.addProduction ( newProd ); } return newCFG; } /** * Opens the convert dialog * * @param convertGrammarType The {@link ConvertGrammarType} */ public void convert ( ConvertGrammarType convertGrammarType ) { this.convertType = convertGrammarType; this.gui = new ConvertGrammarDialogForm ( this, this.parent ); if ( this.convertType.equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ) { this.gui.setTitle ( Messages .getString ( "ConvertGrammarDialog.TitleEliminateLeftRecursion" ) ); //$NON-NLS-1$ } else if ( this.convertType.equals ( ConvertGrammarType.LEFT_FACTORING ) ) { this.gui.setTitle ( Messages .getString ( "ConvertGrammarDialog.TitleFactoring" ) ); //$NON-NLS-1$ } else if ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_ENTITY_PRODUCTIONS ) ) { this.gui .setTitle ( Messages .getString ( "ConvertGrammarDialog.TitleEliminateEntityProductions" ) ); //$NON-NLS-1$ } else if ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_EPSILON_PRODUCTIONS ) ) { this.gui .setTitle ( Messages .getString ( "ConvertGrammarDialog.TitleEliminateEpsilonProductions" ) ); //$NON-NLS-1$ } else { throw new IllegalArgumentException ( "illegal convert grammar type: " //$NON-NLS-1$ + convertGrammarType ); } this.gui.styledNonterminalSymbolSetParserPanelConverted .setVisible ( !this.convertType .equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ); this.gui.jScrollPaneNonterminalsConverted.setVisible ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ); this.gui.jGTIPanelPreferences.setVisible ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ); this.convertMachineTableModel = new ConvertMachineTableModel (); this.gui.jGTITableOutline.setModel ( this.convertMachineTableModel ); this.modelOriginal = ( DefaultGrammarModel ) this.panel.getModel (); this.gui.jGTITableGrammarOriginal.setModel ( this.modelOriginal .getGrammar () ); this.gui.jGTITableGrammarOriginal .setColumnModel ( this.grammarColumnModelOriginal ); this.gui.jGTITableGrammarOriginal.getTableHeader ().setReorderingAllowed ( false ); updateOriginal (); createConverted (); this.gui.jGTITableGrammarConverted.setModel ( this.modelConverted .getGrammar () ); this.gui.jGTITableGrammarConverted .setColumnModel ( this.grammarColumnModelConverted ); this.gui.jGTITableGrammarConverted.getTableHeader ().setReorderingAllowed ( false ); if ( this.convertType.equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ) { this.gui.jGTIListNonterminalsConverted .setDndMode ( JGTIList.DROP_BETWEEN ); this.gui.jGTIListNonterminalsConverted .setCellRenderer ( new PrettyStringListCellRenderer () ); this.gui.jGTIListNonterminalsConverted .setTransferHandler ( new JGTIListTransferHandler ( TransferHandler.MOVE ) { /** * The serial version uid. */ private static final long serialVersionUID = -6137236787378034581L; /** * {@inheritDoc} * * @see de.unisiegen.gtitool.ui.swing.dnd.JGTIListTransferHandler#importListModelRows(de.unisiegen.gtitool.ui.swing.JGTIList, * de.unisiegen.gtitool.ui.swing.dnd.JGTIListModelRows, int) */ @Override protected boolean importListModelRows ( JGTIList list, JGTIListModelRows rows, int targetIndex ) { moveNonterminals ( list, rows, targetIndex ); return true; } } ); this.gui.jGTIListNonterminalsConverted.setDragEnabled ( true ); this.gui.jGTIListNonterminalsConverted .addAllowedDndSource ( this.gui.jGTIListNonterminalsConverted ); } this.modelConverted .addModifyStatusChangedListener ( new ModifyStatusChangedListener () { /** * {@inheritDoc} * * @see de.unisiegen.gtitool.core.entities.listener.ModifyStatusChangedListener#modifyStatusChanged(boolean) */ public void modifyStatusChanged ( @SuppressWarnings ( "unused" ) boolean modified ) { updateConverted (); } } ); updateConverted (); setStatus (); show (); } /** * Creates the converted {@link CFG} initial */ private void createConverted () { NonterminalSymbol start = null; NonterminalSymbolSet nonterminalSet = new DefaultNonterminalSymbolSet (); for ( NonterminalSymbol s : this.modelOriginal.getGrammar () .getNonterminalSymbolSet () ) { NonterminalSymbol c = new DefaultNonterminalSymbol ( new String ( s .getName () ) ); try { nonterminalSet.add ( c ); } catch ( NonterminalSymbolSetException exc ) { exc.printStackTrace (); } if ( s.equals ( this.modelOriginal.getGrammar ().getStartSymbol () ) ) { start = c; } } TerminalSymbolSet terminals = new DefaultTerminalSymbolSet (); for ( TerminalSymbol s : this.modelOriginal.getGrammar () .getTerminalSymbolSet () ) { try { terminals .add ( new DefaultTerminalSymbol ( new String ( s.getName () ) ) ); } catch ( TerminalSymbolSetException exc ) { exc.printStackTrace (); } } CFG newCFG = new DefaultCFG ( nonterminalSet, terminals, start ); for ( Production p : this.modelOriginal.getGrammar ().getProduction () ) { NonterminalSymbol nonterminal = null; for ( NonterminalSymbol s : nonterminalSet ) { if ( p.getNonterminalSymbol ().getName ().equals ( new String ( s.getName () ) ) ) { nonterminal = s; } } ProductionWord word = new DefaultProductionWord (); for ( ProductionWordMember m : p.getProductionWord () ) { for ( NonterminalSymbol n : nonterminalSet ) { if ( m.getName ().equals ( n.getName () ) ) { word.add ( n ); } } for ( TerminalSymbol t : terminals ) { if ( m.getName ().equals ( t.getName () ) ) { word.add ( t ); } } } newCFG.addProduction ( new DefaultProduction ( nonterminal, word ) ); } for ( NonterminalSymbol n : nonterminalSet.get () ) { this.nonterminals.addElement ( n ); } this.initialNonterminalSize = this.nonterminals.size (); this.gui.jGTIListNonterminalsConverted.setModel ( this.nonterminals ); this.modelConverted = new DefaultGrammarModel ( newCFG ); } /** * Eliminates the DirectLeftRecursion for a {@link NonterminalSymbol} in a * {@link CFG} * * @param s The {@link NonterminalSymbol} * @param cfg The {@link CFG} * @throws NonterminalSymbolSetException When new {@link NonterminalSymbol} * could not be created */ private void eliminateDirectLeftRecursion ( NonterminalSymbol s, CFG cfg ) throws NonterminalSymbolSetException { ArrayList < Production > leftRecursions = getDirectLeftRecursion ( s, cfg ); if ( !leftRecursions.isEmpty () ) { DefaultNonterminalSymbol otherS = new DefaultNonterminalSymbol ( s .getName () + "'" ); //$NON-NLS-1$ otherS.setHighlighted ( true ); cfg.getNonterminalSymbolSet ().add ( otherS ); this.nonterminals.addElement ( otherS ); ArrayList < Production > otherProductions = new ArrayList < Production > (); otherProductions.addAll ( cfg.getProductionForNonTerminal ( s ) ); otherProductions.removeAll ( leftRecursions ); for ( Production p : otherProductions ) { p.getProductionWord ().add ( otherS ); } for ( Production p : leftRecursions ) { p.setNonterminalSymbol ( otherS ); p.getProductionWord ().get ().remove ( 0 ); p.getProductionWord ().add ( otherS ); } Production p = new DefaultProduction ( otherS, new DefaultProductionWord () ); p.setHighlighted ( true ); cfg.addProduction ( p ); } } /** * Eliminates entity productions from a {@link CFG} * * @param cfg The {@link CFG} */ private void eliminateEntityProductions ( CFG cfg ) { ArrayList < Production > tmpEntityProductions = getEntityProductions ( cfg ); for ( Production p : tmpEntityProductions ) { NonterminalSymbol a = p.getNonterminalSymbol (); NonterminalSymbol b = ( NonterminalSymbol ) p.getProductionWord ().get ( 0 ); for ( Production p2 : cfg.getProductionForNonTerminal ( b ) ) { Production newProd = new DefaultProduction ( a, p2.getProductionWord () ); newProd.setHighlighted ( true ); if ( !cfg.getProduction ().contains ( newProd ) ) { cfg.addProduction ( newProd ); } } cfg.getProduction ().remove ( p ); } if ( !getEntityProductions ( cfg ).isEmpty () ) { eliminateEntityProductions ( cfg ); } } /** * Eliminates the EpsilonProductions from a {@link CFG} * * @param cfg The {@link CFG} */ private void eliminateEpsilonProductions ( CFG cfg ) { ArrayList < NonterminalSymbol > symbolsToEpsilon = new ArrayList < NonterminalSymbol > (); for ( Production p : getEpsilonProductions ( cfg ) ) { symbolsToEpsilon.add ( p.getNonterminalSymbol () ); if ( !p.getNonterminalSymbol ().equals ( cfg.getStartSymbol () ) ) { cfg.getProduction ().remove ( p ); } } for ( NonterminalSymbol s : symbolsToEpsilon ) { for ( Production p : getProductionsForNonterminal ( s, cfg ) ) { DefaultProductionWord w = new DefaultProductionWord (); for ( ProductionWordMember m : p.getProductionWord ().get () ) { if ( !m.equals ( s ) ) { w.add ( m ); } } Production newProd = new DefaultProduction ( p.getNonterminalSymbol (), w ); newProd.setHighlighted ( true ); cfg.addProduction ( newProd ); } } } /** * Returns the convertMachineTableModel. * * @return The convertMachineTableModel. * @see #convertMachineTableModel */ public ConvertMachineTableModel getConvertMachineTableModel () { return this.convertMachineTableModel; } /** * Gets the direct left recursions of a {@link NonterminalSymbol} in a * {@link CFG} * * @param s The {@link NonterminalSymbol} * @param cfg The {@link CFG} * @return The direct left recursions of a {@link NonterminalSymbol} in a * {@link CFG} */ private ArrayList < Production > getDirectLeftRecursion ( NonterminalSymbol s, CFG cfg ) { ArrayList < Production > productions = new ArrayList < Production > (); for ( Production p : cfg.getProductionForNonTerminal ( s ) ) { if ( ( p.getProductionWord ().size () > 0 ) && p.getProductionWord ().get ( 0 ).getName ().equals ( s.getName () ) ) { productions.add ( p ); } } return productions; } /** * Gets the EntitiyProductions for a {@link CFG} * * @param cfg The {@link CFG} * @return The EntityProductions */ private ArrayList < Production > getEntityProductions ( CFG cfg ) { ArrayList < Production > productions = new ArrayList < Production > (); for ( Production p : cfg.getProduction () ) { if ( ( p.getProductionWord ().size () == 1 ) && ( p.getProductionWord ().get ( 0 ) instanceof NonterminalSymbol ) ) { productions.add ( p ); } } return productions; } /** * Gets the EpsilonProductions of a {@link CFG} * * @param cfg The {@link CFG} * @return EpsilonProductions */ private ArrayList < Production > getEpsilonProductions ( CFG cfg ) { ArrayList < Production > symbols = new ArrayList < Production > (); for ( Production p : cfg.getProduction () ) { if ( p.getProductionWord ().equals ( new DefaultProductionWord () ) ) { symbols.add ( p ); } } return symbols; } /** * Get the gui class * * @see de.unisiegen.gtitool.ui.logic.interfaces.LogicClass#getGUI() */ public ConvertGrammarDialogForm getGUI () { return this.gui; } /** * Returns the {@link JGTITable} converted * * @return The {@link JGTITable} converted */ public JGTITable getJGTITableConverted () { return this.gui.jGTITableGrammarConverted; } /** * Returns the {@link JGTITable} original * * @return The {@link JGTITable} original */ public JGTITable getJGTITableOriginal () { return this.gui.jGTITableGrammarOriginal; } /** * Returns the modelConverted. * * @return The modelConverted. * @see #modelConverted */ public DefaultGrammarModel getModelConverted () { return this.modelConverted; } /** * Returns the modelOriginal. * * @return The modelOriginal. * @see #modelOriginal */ public DefaultGrammarModel getModelOriginal () { return this.modelOriginal; } /** * Returns the panel. * * @return The panel. * @see #panel */ public GrammarPanel getPanel () { return this.panel; } /** * Gets Productions where the {@link NonterminalSymbol} is in the * {@link ProductionWord} * * @param s The {@link NonterminalSymbol} * @param cfg The {@link CFG} * @return Productions where the {@link NonterminalSymbol} is in the * {@link ProductionWord} */ private ArrayList < Production > getProductionsForNonterminal ( NonterminalSymbol s, CFG cfg ) { ArrayList < Production > result = new ArrayList < Production > (); for ( Production p : cfg.getProduction () ) { if ( p.getProductionWord ().get ().contains ( s ) ) { result.add ( p ); } } return result; } /** * Gets the productions for 2 {@link NonterminalSymbol}s * * @param a The first {@link NonterminalSymbol} * @param b The second {@link NonterminalSymbol} * @param cfg The {@link CFG} * @return Productions for 2 {@link NonterminalSymbol}s */ private ArrayList < Production > getProductionsForNonterminals ( NonterminalSymbol a, NonterminalSymbol b, CFG cfg ) { ArrayList < Production > productions = new ArrayList < Production > (); for ( Production p : cfg.getProduction () ) { if ( p.getNonterminalSymbol ().getName ().equals ( a.getName () ) && ( p.getProductionWord ().size () > 0 ) && p.getProductionWord ().get ( 0 ).getName ().equals ( b.getName () ) ) { productions.add ( p ); } } return productions; } /** * Gets the Productions with the prefix * * @param productions The {@link Production}s * @param prefix The prefix as {@link ProductionWord} * @return The {@link Production}s with the prefix */ private ArrayList < Production > getProductionsWithPrefix ( ArrayList < Production > productions, ProductionWord prefix ) { ArrayList < Production > result = new ArrayList < Production > (); for ( Production p : productions ) { ProductionWord word = p.getProductionWord (); boolean fit = true; for ( int k = 0 ; k < prefix.get ().size () ; k++ ) { if ( ( word.size () <= k ) || !prefix.get ( k ).equals ( word.get ( k ) ) ) { fit = false; } } if ( fit ) { result.add ( p ); } } return result; } /** * Gets the same prefixes of a {@link NonterminalSymbol} in a {@link CFG} * * @param a The {@link NonterminalSymbol} * @param cfg The {@link CFG} * @return An {@link ObjectPair} with the prefix and the productions */ private ObjectPair < ProductionWord, ArrayList < Production > > getSamePrefixes ( NonterminalSymbol a, CFG cfg ) { ProductionWord prefix = new DefaultProductionWord (); ArrayList < Production > productions = new ArrayList < Production > (); for ( Production p : cfg.getProductionForNonTerminal ( a ) ) { productions.add ( p ); } while ( !productions.isEmpty () ) { Production p = productions.remove ( 0 ); for ( ProductionWordMember m : p.getProductionWord () ) { prefix.add ( m ); } while ( !prefix.get ().isEmpty () ) { ArrayList < Production > ps = getProductionsWithPrefix ( productions, prefix ); if ( !ps.isEmpty () ) { ps.add ( p ); return new ObjectPair < ProductionWord, ArrayList < Production > > ( prefix, ps ); } prefix.get ().remove ( prefix.get ().size () - 1 ); } } return new ObjectPair < ProductionWord, ArrayList < Production > > ( new DefaultProductionWord (), new ArrayList < Production > () ); } /** * Returns the tableColumnModel. * * @return The tableColumnModel. * @see #tableColumnModel */ public ConvertMachineTableColumnModel getTableColumnModel () { return this.tableColumnModel; } /** * Shows or dispose the Algorithm window * * @param show Show or dispose */ public void handleAlgorithmWindowChanged ( boolean show ) { if ( ( this.algorithm == null ) || ( this.algorithm.length () == 0 ) ) { TextLoader loader = new TextLoader (); this.algorithm = loader.loadAlgorithm ( this.convertType ); } if ( this.algorithmWindow == null ) { this.algorithmWindow = new TextWindow ( this.gui, this.algorithm, true, this.gui.jGTIToggleButtonAlgorithm, this.convertType.toString () ); } if ( show ) { this.algorithmWindow.show (); } else { this.algorithmWindow.dispose (); } } /** * Handles the action on the auto step button. */ public void handleAutoStep () { logger.debug ( "handleAutoStep", "handle auto step" ); //$NON-NLS-1$ //$NON-NLS-2$ setStatus (); startAutoStepTimer (); } /** * Handles the action on the begin step button. */ public void handleBeginStep () { logger.debug ( "handleBeginStep", "handle begin step" ); //$NON-NLS-1$ //$NON-NLS-2$ while ( !this.stepItemList.isEmpty () ) { handlePreviousStep (); } } /** * Handles the action on the cancel button. */ public void handleCancel () { logger.debug ( "handleCancel", "handle cancel" ); //$NON-NLS-1$ //$NON-NLS-2$ this.gui.dispose (); } /** * Handles the action on the end step button. */ public void handleEndStep () { logger.debug ( "handleEndStep", "handle end step" ); //$NON-NLS-1$ //$NON-NLS-2$ while ( !this.endReached ) { handleNextStep (); } } /** * Handles the action on the next step button. */ public void handleNextStep () { logger.debug ( "handleNextStep", "handle next step" ); //$NON-NLS-1$ //$NON-NLS-2$ performNextStep (); setStatus (); } /** * Handles the action on the ok button. */ public void handleOk () { logger.debug ( "handleOk", "handle ok" ); //$NON-NLS-1$ //$NON-NLS-2$ cancelAutoStepTimer (); while ( !this.endReached ) { performNextStep (); } this.gui.setVisible ( false ); this.panel.getMainWindow ().handleNew ( this.modelConverted.getElement (), false ); this.gui.dispose (); } /** * Handles the action on the previous step button. */ public void handlePreviousStep () { logger.debug ( "handlePrevious", "handle previous" ); //$NON-NLS-1$ //$NON-NLS-2$ performPreviousStep (); } /** * Handles the action on the print button. */ public void handlePrint () { PrintDialog dialog = new PrintDialog ( this.parent, this ); dialog.show (); } /** * Handles the action on the stop button. */ public void handleStop () { logger.debug ( "handleStop", "handle stop" ); //$NON-NLS-1$ //$NON-NLS-2$ cancelAutoStepTimer (); this.gui.jGTIToolBarToggleButtonAutoStep.setSelected ( false ); setStatus (); } /** * Left factoring of a {@link NonterminalSymbol} in a {@link CFG} * * @param a The {@link NonterminalSymbol} * @param cfg The {@link CFG} */ private void leftFactore ( NonterminalSymbol a, CFG cfg ) { ObjectPair < ProductionWord, ArrayList < Production > > objectPair = getSamePrefixes ( a, cfg ); ProductionWord prefix = objectPair.getFirst (); ArrayList < Production > productions = objectPair.getSecond (); if ( ! ( prefix.get ().size () == 0 ) && !productions.isEmpty () ) { NonterminalSymbol newSymbol = new DefaultNonterminalSymbol ( a.getName () + "'" ); //$NON-NLS-1$ newSymbol.setHighlighted ( true ); try { cfg.getNonterminalSymbolSet ().add ( newSymbol ); } catch ( NonterminalSymbolSetException exc ) { exc.printStackTrace (); } ProductionWord newWord = new DefaultProductionWord ( prefix.get () ); newWord.add ( newSymbol ); Production prod = new DefaultProduction ( a, newWord ); prod.setHighlighted ( true ); cfg.addProduction ( prod ); for ( int k = 0 ; k < productions.size () ; k++ ) { Production p = productions.get ( k ); ProductionWord word = new DefaultProductionWord (); for ( int l = prefix.get ().size () ; l < p.getProductionWord () .size () ; l++ ) { word.add ( p.getProductionWord ().get ( l ) ); } Production pr = new DefaultProduction ( newSymbol, word ); pr.setHighlighted ( true ); cfg.addProduction ( pr ); cfg.getProduction ().remove ( p ); } } } /** * Moves {@link NonterminalSymbol}s in the {@link JGTIList} * * @param list The List * @param rows The rows to move * @param targetIndex The new index */ protected void moveNonterminals ( @SuppressWarnings ( "unused" ) JGTIList list, JGTIListModelRows rows, int targetIndex ) { ArrayList < NonterminalSymbol > oldNonterminals = new ArrayList < NonterminalSymbol > (); for ( int n = 0 ; n < this.nonterminals.getSize () ; n++ ) { oldNonterminals.add ( ( NonterminalSymbol ) this.nonterminals.get ( n ) ); } ArrayList < NonterminalSymbol > nonterminalList = new ArrayList < NonterminalSymbol > (); int [] indeces = rows.getRowIndices (); int newTargetIndex = targetIndex; if ( ( indeces.length > 0 ) && ( indeces [ 0 ] < targetIndex ) ) { newTargetIndex++ ; } for ( int index : indeces ) { nonterminalList.add ( ( NonterminalSymbol ) this.nonterminals .getElementAt ( index ) ); if ( index < targetIndex ) { newTargetIndex-- ; } } for ( int n = indeces.length - 1 ; n > -1 ; n-- ) { this.nonterminals.remove ( indeces [ n ] ); } newTargetIndex = Math.min ( newTargetIndex, this.nonterminals.getSize () ); Collections.reverse ( nonterminalList ); for ( NonterminalSymbol s : nonterminalList ) { this.nonterminals.add ( newTargetIndex, s ); } this.gui.jGTIListNonterminalsConverted.getSelectionModel () .setSelectionInterval ( newTargetIndex, newTargetIndex + indeces.length - 1 ); } /** * Performs the next step. */ private final void performNextStep () { CFG oldCFG = cloneConverted (); CFG cfg = ( CFG ) this.modelConverted.getGrammar (); boolean foundProduction = false; ArrayList < Production > oldWorkingProductions = new ArrayList < Production > (); if ( this.workingProductions != null ) { oldWorkingProductions.addAll ( this.workingProductions ); } for ( Production p : cfg.getProduction () ) { p.setHighlighted ( false ); } for ( NonterminalSymbol s : cfg.getNonterminalSymbolSet () ) { s.setHighlighted ( false ); } if ( this.convertType.equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ) { DefaultListModel oldNonterminalModel = new DefaultListModel (); for ( int n = 0 ; n < this.nonterminals.size () ; n++ ) { oldNonterminalModel.addElement ( this.nonterminals.getElementAt ( n ) ); } int iNow = this.i; int jNow = this.j; ArrayList < Production > entitiyProductions = new ArrayList < Production > (); if ( this.gui.jGTICheckBoxEntityProductions.isSelected () ) { entitiyProductions = getEntityProductions ( cfg ); } ArrayList < Production > eProductions = new ArrayList < Production > (); if ( this.gui.jGTICheckBoxEpsilonProductions.isSelected () ) { eProductions = getEpsilonProductions ( cfg ); } if ( entitiyProductions.isEmpty () ) { this.initialEliminateEntityProductionsDone = true; } if ( eProductions.isEmpty () ) { this.initialEliminateEpsilonProductionsDone = true; } PrettyString line = new PrettyString (); if ( ( !this.initialEliminateEntityProductionsDone || !this.initialEliminateEpsilonProductionsDone ) ) { if ( !entitiyProductions.isEmpty () ) { eliminateEntityProductions ( cfg ); line .add ( new PrettyToken ( Messages .getString ( "ConvertGrammarDialog.EliminatedEntityProductions" ), Style.COMMENT ) ); //$NON-NLS-1$ this.initialEliminateEntityProductionsDone = true; } else if ( !eProductions.isEmpty () ) { line .add ( new PrettyToken ( Messages .getString ( "ConvertGrammarDialog.EliminatedEpsilonProductions" ), Style.COMMENT ) ); //$NON-NLS-1$ eliminateEpsilonProductions ( cfg ); this.initialEliminateEpsilonProductionsDone = true; } } else { line.add ( new PrettyToken ( "i: ", Style.KEYWORD ) ); //$NON-NLS-1$ line .add ( new PrettyToken ( Integer.toString ( this.i ), Style.SYMBOL ) ); line.add ( new PrettyToken ( " j: ", Style.KEYWORD ) ); //$NON-NLS-1$ line .add ( new PrettyToken ( Integer.toString ( this.j ), Style.SYMBOL ) ); line.add ( new PrettyToken ( "; ", Style.KEYWORD ) ); //$NON-NLS-1$ // for ( int i = 1 ; i <= nonterminals.size () ; i++ ) if ( this.i <= this.initialNonterminalSize ) { NonterminalSymbol ai = ( NonterminalSymbol ) this.nonterminals .getElementAt ( this.i - 1 ); // for ( int j = 0 ; j < this.i - 1 ; j++ ) line.add ( new PrettyToken ( "Ai: ", Style.KEYWORD ) ); //$NON-NLS-1$ line.add ( ai.toPrettyString () ); if ( this.j <= this.i - 1 ) { NonterminalSymbol aj = ( NonterminalSymbol ) this.nonterminals .getElementAt ( this.j - 1 ); line.add ( new PrettyToken ( "; Aj: ", Style.KEYWORD ) ); //$NON-NLS-1$ line.add ( aj.toPrettyString () ); this.j++ ; ArrayList < Production > productions = getProductionsForNonterminals ( ai, aj, cfg ); ArrayList < Production > productionsOfAj = cfg .getProductionForNonTerminal ( aj ); for ( Production pi : productions ) { cfg.getProduction ().remove ( pi ); pi.getProductionWord ().get ().remove ( 0 ); for ( Production pj : productionsOfAj ) { ProductionWord word = new DefaultProductionWord ( pj .getProductionWord ().get () ); word.add ( pi.getProductionWord ().get () ); Production p = new DefaultProduction ( ai, word ); p.setHighlighted ( true ); cfg.addProduction ( p ); } } } else { try { eliminateDirectLeftRecursion ( ai, cfg ); } catch ( NonterminalSymbolSetException exc ) { exc.printStackTrace (); } this.j = 1; this.i++ ; if ( this.i > this.initialNonterminalSize ) { this.endReached = true; } } } else { this.endReached = true; } } addOutlineComment ( line ); this.stepItemList.add ( new StepItem ( oldCFG, oldNonterminalModel, iNow, jNow, null, foundProduction, oldWorkingProductions ) ); } else if ( this.convertType.equals ( ConvertGrammarType.LEFT_FACTORING ) ) { NonterminalSymbol a = null; ProductionWord prefix = null; for ( NonterminalSymbol s : cfg.getNonterminalSymbolSet () ) { ObjectPair < ProductionWord, ArrayList < Production > > pair = getSamePrefixes ( s, cfg ); if ( pair.getFirst ().size () > 0 ) { a = s; prefix = pair.getFirst (); break; } } if ( a != null ) { leftFactore ( a, cfg ); } this.stepItemList.add ( new StepItem ( oldCFG, null, 0, 0, null, foundProduction, oldWorkingProductions ) ); this.endReached = true; for ( NonterminalSymbol s : cfg.getNonterminalSymbolSet () ) { if ( getSamePrefixes ( s, cfg ).getFirst ().size () > 0 ) { this.endReached = false; break; } } PrettyString line = new PrettyString (); if ( ( a != null ) && ( prefix != null ) ) { line.add ( Messages.getPrettyString ( "ConvertGrammarDialog.StepFactor", a.toPrettyString (), prefix //$NON-NLS-1$ .toPrettyString () ) ); } else { line.add ( Messages .getPrettyString ( "ConvertGrammarDialog.StepNothingToDo" ) ); //$NON-NLS-1$ } addOutlineComment ( line ); } // Eliminate Entity Productions else if ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_ENTITY_PRODUCTIONS ) ) { PrettyString line = new PrettyString (); if ( this.entityProductions == null ) { this.entityProductions = getEntityProductions ( cfg ); this.workingProductions = new ArrayList < Production > (); this.i = 0; this.j = 0; } Production addedProduction = null; int iNow = this.i; int jNow = this.j; if ( !this.entityProductions.isEmpty () ) { if ( this.i < this.entityProductions.size () ) { // Right side of entity production must be a nonterminal NonterminalSymbol a = this.entityProductions.get ( this.i ) .getNonterminalSymbol (); NonterminalSymbol b = ( NonterminalSymbol ) this.entityProductions .get ( this.i ).getProductionWord ().get ( 0 ); if ( this.workingProductions.isEmpty () ) { // Found new entity production this.workingProductions.addAll ( cfg .getProductionForNonTerminal ( b ) ); this.j = 0; foundProduction = true; line.add ( Messages.getPrettyString ( "ConvertGrammarDialog.StepEntityProductionFound",//$NON-NLS-1$ this.entityProductions.get ( this.i ).toPrettyString () ) ); } else { // Eliminate entity production Production p = this.workingProductions.get ( this.j++ ); Production newProd = new DefaultProduction ( a, p .getProductionWord () ); newProd.setHighlighted ( true ); if ( !cfg.getProduction ().contains ( newProd ) ) { cfg.addProduction ( newProd ); if ( ( newProd.getProductionWord ().size () == 1 ) && ( newProd.getProductionWord ().get ( 0 ) instanceof NonterminalSymbol ) ) { this.entityProductions.add ( newProd ); } } line.add ( Messages.getPrettyString ( "ConvertGrammarDialog.StepCreatedProduction", newProd //$NON-NLS-1$ .toPrettyString () ) ); } if ( this.j >= this.workingProductions.size () ) { this.workingProductions.clear (); this.i++ ; } } else { line .add ( Messages .getPrettyString ( "ConvertGrammarDialog.EliminatedEntityProductions" ) ); //$NON-NLS-1$ cfg.getProduction ().removeAll ( this.entityProductions ); this.endReached = true; } } else { line .add ( Messages .getPrettyString ( "ConvertGrammarDialog.StepNoEntityProductions" ) ); //$NON-NLS-1$ this.endReached = true; } this.stepItemList.add ( new StepItem ( oldCFG, null, iNow, jNow, addedProduction, foundProduction, oldWorkingProductions ) ); addOutlineComment ( line ); } // Eliminate Epsilon Productions else if ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_EPSILON_PRODUCTIONS ) ) { PrettyString line = new PrettyString (); if ( this.epsilonProductions == null ) { this.epsilonProductions = getEpsilonProductions ( cfg ); this.workingProductions = new ArrayList < Production > (); this.i = 0; this.j = 0; } int iNow = this.i; int jNow = this.j; Production addedEpsilonProduction = null; if ( !this.epsilonProductions.isEmpty () ) { if ( this.i < this.epsilonProductions.size () ) { NonterminalSymbol s = this.epsilonProductions.get ( this.i ) .getNonterminalSymbol (); if ( this.workingProductions.isEmpty () ) { // New epsilon production found this.workingProductions.addAll ( getProductionsForNonterminal ( s, cfg ) ); this.j = 0; foundProduction = true; line.add ( Messages.getPrettyString ( "ConvertGrammarDialog.StepEpsilonProductionFound", s //$NON-NLS-1$ .toPrettyString () ) ); } else { // Eliminate nonterminal in production word DefaultProductionWord w = new DefaultProductionWord (); Production p = this.workingProductions.get ( this.j++ ); for ( ProductionWordMember m : p.getProductionWord ().get () ) { if ( !m.equals ( s ) ) { w.add ( m ); } } Production newProduction = new DefaultProduction ( p .getNonterminalSymbol (), w ); newProduction.setHighlighted ( true ); if ( w.get ().isEmpty () ) { // If created an epsilon production add it to the arraylist if ( !this.epsilonProductions.contains ( newProduction ) ) { this.epsilonProductions.add ( newProduction ); addedEpsilonProduction = newProduction; } } line.add ( Messages.getPrettyString ( "ConvertGrammarDialog.StepCreatedProduction", newProduction //$NON-NLS-1$ .toPrettyString () ) ); if ( !cfg.getProduction ().contains ( newProduction ) ) { cfg.addProduction ( newProduction ); } } if ( this.j >= this.workingProductions.size () ) { this.workingProductions.clear (); this.i++ ; } } else { line .add ( Messages .getPrettyString ( "ConvertGrammarDialog.EliminatedEpsilonProductions" ) ); //$NON-NLS-1$ for ( Production p : this.epsilonProductions ) { if ( !p.getNonterminalSymbol ().equals ( cfg.getStartSymbol () ) ) { cfg.getProduction ().remove ( p ); } } this.endReached = true; } } else { line .add ( Messages .getPrettyString ( "ConvertGrammarDialog.StepNoEpsilonProductions" ) ); //$NON-NLS-1$ this.endReached = true; } this.stepItemList.add ( new StepItem ( oldCFG, null, iNow, jNow, addedEpsilonProduction, foundProduction, oldWorkingProductions ) ); addOutlineComment ( line ); } this.gui.repaint (); updateConverted (); setStatus (); } /** * Performs previous step */ private void performPreviousStep () { StepItem item = this.stepItemList.remove ( this.stepItemList.size () - 1 ); CFG old = item.getOldCFG (); this.modelConverted = new DefaultGrammarModel ( old ); this.gui.jGTITableGrammarConverted.setModel ( this.modelConverted .getGrammar () ); this.gui.jGTITableGrammarConverted .setColumnModel ( this.grammarColumnModelConverted ); this.gui.jGTITableGrammarConverted.getTableHeader ().setReorderingAllowed ( false ); if ( this.convertType.equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ) { this.i = item.getINow (); this.j = item.getJNow (); if ( ( this.i == 1 ) && ( this.j == 1 ) ) { if ( this.initialEliminateEntityProductionsDone ) { this.initialEliminateEntityProductionsDone = false; } if ( this.initialEliminateEpsilonProductionsDone ) { this.initialEliminateEpsilonProductionsDone = false; } } this.nonterminals = item.getOldNonterminalModel (); this.gui.jGTIListNonterminalsConverted.setModel ( this.nonterminals ); } if ( this.convertType .equals ( ConvertGrammarType.ELIMINATE_EPSILON_PRODUCTIONS ) || this.convertType .equals ( ConvertGrammarType.ELIMINATE_ENTITY_PRODUCTIONS ) ) { this.i = item.getINow (); this.j = item.getJNow (); Production p = item.getAddedEpsilonProduction (); if ( p != null ) { this.modelConverted.getGrammar ().getProduction ().remove ( p ); } } this.workingProductions = new ArrayList < Production > (); this.workingProductions.addAll ( item.getWorkingProductions () ); if ( item.isFoundProduction () ) { this.workingProductions.clear (); } updateConverted (); this.convertMachineTableModel.removeLastRow (); this.endReached = false; setStatus (); } /** * Sets the button status. */ private final void setStatus () { if ( this.gui.jGTIToolBarToggleButtonAutoStep.isSelected () ) { this.gui.jGTIToolBarButtonBeginStep.setEnabled ( false ); this.gui.jGTIToolBarButtonPreviousStep.setEnabled ( false ); this.gui.jGTIToolBarButtonNextStep.setEnabled ( false ); this.gui.jGTIToolBarToggleButtonAutoStep.setEnabled ( false ); this.gui.jGTIToolBarButtonStop.setEnabled ( true ); this.gui.jGTIToolBarButtonEndStep.setEnabled ( false ); this.gui.jGTIListNonterminalsConverted.setDragEnabled ( false ); this.gui.jGTICheckBoxEntityProductions.setEnabled ( false ); this.gui.jGTICheckBoxEpsilonProductions.setEnabled ( false ); } else { boolean beginReached = this.stepItemList.isEmpty (); this.gui.jGTIListNonterminalsConverted.setDragEnabled ( beginReached ); this.gui.jGTICheckBoxEntityProductions.setEnabled ( beginReached ); this.gui.jGTICheckBoxEpsilonProductions.setEnabled ( beginReached ); this.gui.jGTIToolBarButtonBeginStep.setEnabled ( !beginReached ); this.gui.jGTIToolBarButtonPreviousStep.setEnabled ( !beginReached ); this.gui.jGTIToolBarButtonNextStep.setEnabled ( !this.endReached ); this.gui.jGTIToolBarToggleButtonAutoStep.setEnabled ( !this.endReached ); this.gui.jGTIToolBarButtonStop.setEnabled ( false ); this.gui.jGTIToolBarButtonEndStep.setEnabled ( !this.endReached ); } } /** * Shows the {@link ConvertMachineDialogForm}. */ public final void show () { logger.debug ( "show", "show the convert machine dialog" ); //$NON-NLS-1$ //$NON-NLS-2$ Rectangle rect = PreferenceManager.getInstance () .getConvertMachineDialogBounds (); if ( ( rect.x == PreferenceManager.DEFAULT_CONVERT_MACHINE_DIALOG_POSITION_X ) || ( rect.y == PreferenceManager.DEFAULT_CONVERT_MACHINE_DIALOG_POSITION_Y ) ) { rect.x = this.parent.getBounds ().x + ( this.parent.getWidth () / 2 ) - ( this.gui.getWidth () / 2 ); rect.y = this.parent.getBounds ().y + ( this.parent.getHeight () / 2 ) - ( this.gui.getHeight () / 2 ); } this.gui.setBounds ( rect ); this.gui.setVisible ( true ); } /** * Starts the auto step timer. */ @SuppressWarnings ( "synthetic-access" ) private final void startAutoStepTimer () { cancelAutoStepTimer (); this.autoStepTimer = new Timer (); int time = PreferenceManager.getInstance ().getAutoStepItem () .getAutoStepInterval (); this.autoStepTimer.schedule ( new AutoStepTimerTask (), time, time ); } /** * Updates the converted {@link CFG} */ protected void updateConverted () { if ( !this.convertType .equals ( ConvertGrammarType.ELIMINATE_LEFT_RECURSION ) ) { this.gui.styledNonterminalSymbolSetParserPanelConverted .setText ( this.modelConverted.getGrammar () .getNonterminalSymbolSet () ); } this.gui.styledStartNonterminalSymbolParserPanelConverted .setText ( this.modelConverted.getGrammar ().getStartSymbol () ); this.gui.styledTerminalSymbolSetParserPanelConverted .setText ( this.modelConverted.getGrammar ().getTerminalSymbolSet () ); } /** * Updates the original {@link CFG} */ private void updateOriginal () { this.gui.styledNonterminalSymbolSetParserPanelOriginal .setText ( this.modelOriginal.getGrammar ().getNonterminalSymbolSet () ); this.gui.styledStartNonterminalSymbolParserPanelOriginal .setText ( this.modelOriginal.getGrammar ().getStartSymbol () ); this.gui.styledTerminalSymbolSetParserPanelOriginal .setText ( this.modelOriginal.getGrammar ().getTerminalSymbolSet () ); } }