package agg.gui.parser; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Enumeration; import java.util.Vector; import javax.swing.JCheckBox; //import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; import agg.gui.AGGAppl; import agg.gui.event.EditEventListener; import agg.gui.event.EditEvent; import agg.attribute.impl.AttrTupleManager; import agg.editor.impl.EdGraGra; import agg.gui.options.OptionGUI; import agg.gui.options.ParserGUIOption; import agg.gui.options.ParserOptionGUI; import agg.gui.parser.event.OptionListener; import agg.gui.parser.event.StatusMessageEvent; import agg.gui.parser.event.StatusMessageListener; import agg.gui.treeview.GraGraTreeView; import agg.parser.CriticalPairOption; import agg.parser.ExcludePairContainer; import agg.parser.ExcludeParser; import agg.parser.LayerOption; import agg.parser.LayeredExcludePairContainer; import agg.parser.PairContainer; import agg.parser.Parser; import agg.parser.ParserEvent; import agg.parser.ParserEventListener; import agg.parser.ParserFactory; import agg.parser.ParserMessageEvent; import agg.parser.ParserOption; import agg.parser.SimpleParser; import agg.xt_basis.OrdinaryMorphism; import agg.xt_basis.RuleLayer; import agg.util.Pair; /** * The class creates an AGG parser. * * @author $Author: olga $ * @version $ID */ public class AGGParser implements ParserEventListener, OptionListener, EditEventListener { /** Creates a new instance of the AGG parser */ public AGGParser(AGGAppl appl, GraGraTreeView treeView) { this.parent = appl; this.treeView = treeView; this.listener = new Vector<ParserEventListener>(); this.pmlistener = new Vector<StatusMessageListener>(); this.option = new ParserGUIOption(); this.lOption = new LayerOption(); this.lOptionGUI = new LayerOptionGUI(this.lOption); this.lOption.addOptionListener(this.lOptionGUI); this.pOption = new ParserOption(); this.pOptionGUI = new ParserOptionGUI(this.option, this.pOption, this.cpOption); this.parserDesktop = new ParserDesktop(this, this.option, null, null, null); this.menus = new Vector<JMenu>(2); this.menu = new JMenu("Parser", true); // menu.setMnemonic('r'); this.openP = new JMenuItem("Open Shift+Alt+P"); this.openP.setMnemonic('O'); this.startP = new JMenuItem("Start Shift+Alt+S"); this.startP.setMnemonic('S'); this.stopP = new JMenuItem("Stop Shift+Alt+Q"); this.stopP.setMnemonic('p'); this.backP = new JMenuItem("back Shift+Alt+Z"); this.backP.setMnemonic('b'); this.options = new JMenuItem("Options..."); createParserMenu(); addParserEventListener(this); this.changer = new GUIExchange(this.parent); } public void editEventOccurred(EditEvent e) { // System.out.println("AGGParser.editEventOccurred "+e.getObject()); if (e.getMsg() == EditEvent.MENU_KEY) { if (e.getMessage().equals("Parser")) this.menu.doClick(); else if (e.getMessage().equals("Parser Open")) openParserDialog(); } } protected void showOptionGUI() { if (this.parent != null) { this.parent.getPreferences().showOptionGUI(OptionGUI.PARSER); } } public Enumeration<JMenu> getMenus() { return this.menus.elements(); } public ParserGUIOption getParserGUIOption() { return this.option; } public LayerOption getLayerOption() { return this.lOption; } public LayerOptionGUI getLayerOptionGUI() { return this.lOptionGUI; } public ParserOption getParserOption() { return this.pOption; } public ParserOptionGUI getParserOptionGUI() { return this.pOptionGUI; } public void setCriticalPairOption(CriticalPairOption cpOption) { this.cpOption = cpOption; this.pOptionGUI.setCriticalPairOption(cpOption); cpOption.addOptionListener(this.pOptionGUI); } /* Implements agg.parser.ParserEventListener */ public void parserEventOccured(ParserEvent e) { // System.out.println("AGGParser.parserEventOccured "+e.getMessage()); if ((e.getMessage().indexOf("Critical") != -1) && (e.getMessage().indexOf("finished") != -1)) { if (this.activeParser && this.generateCP) { this.generateCP = false; fireParserEvent(new ParserMessageEvent(this, " Please choice menu - Parser / Start - to start parsing")); } } else if (e.getMessage().indexOf("Result") != -1) { this.startP.setEnabled(false); this.stopP.setEnabled(false); this.pairsGraGra.setChanged(false); this.hostGraphGrammar.setChanged(false); this.stopGraphGrammar.setChanged(false); } } /* Implements agg.gui.parser.event.OptionListener */ public void optionEventOccurred(agg.gui.parser.event.OptionEvent e) { // System.out.println("AGGParser.optionEventOccurred"); if (e.getSource() instanceof JCheckBox) { JCheckBox cb = (JCheckBox) e.getSource(); // System.out.println(cb.getText()+" "+cb.isSelected()); if (cb.getText().equals("NACs")) { this.cpOption.enableNacs(cb.isSelected()); } else if (cb.getText().equals("PACs")) { this.cpOption.enablePacs(cb.isSelected()); } } } /** Creates a parser menu */ protected void createParserMenu() { this.openP.setEnabled(true); this.menu.add(this.openP); this.openP.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { openParserDialog(); } }); this.startP.setEnabled(false); this.menu.add(this.startP); this.startP.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { startParser(); } }); this.stopP.setEnabled(false); this.menu.add(this.stopP); this.stopP.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stopParser(); } }); this.backP.setEnabled(false); this.menu.add(this.backP); this.backP.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { backToGUI(); } }); this.menu.addSeparator(); this.menu.add(this.options); this.options.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { showOptionGUI(); } }); this.menus.addElement(this.menu); } public void openParserDialog() { this.parserStartDialog = new ParserDialog(this.parent, this.treeView, this.pOption, this.cpOption, this.lOption); /* * if(pOption.getSelectedParser() != ParserOption.SIMPLEPARSER){ * javax.swing.JOptionPane.showMessageDialog(null, "Please * note:\nParsing is not possible for graph grammars \nwith node type * inheritance.", "Warning", javax.swing.JOptionPane.WARNING_MESSAGE); } */ this.parserStartDialog.showDialog(); if (this.parserStartDialog.isReadyToParse()) { this.hostGraphGrammar = this.parserStartDialog.getHostGraphGrammar(); this.stopGraphGrammar = this.parserStartDialog.getStopGraphGrammar(); this.tmpPairs = this.parserStartDialog.getCriticalPairs(); this.pairsGraGra = this.stopGraphGrammar; if (this.pairsGraGra.getBasisGraGra() == null) { javax.swing.JOptionPane.showMessageDialog(null, "Parsing grammar does not exist.", "Warning", javax.swing.JOptionPane.ERROR_MESSAGE); fireParserEvent(new ParserMessageEvent(this, "Thread - Parsing - was stopped.")); return; } // if (pOption.getSelectedParser() != ParserOption.SIMPLEPARSER) { // if (hostGraphGrammar.getBasisGraGra().getTypeSet() // .usesInheritance() // || pairsGraGra.getBasisGraGra().getTypeSet() // .usesInheritance()) { // javax.swing.JOptionPane // .showMessageDialog( // null, // "Sorry!\nParsing based on critical pairs is not possible " // + "\nfor graph grammars with node type inheritance." // + "\nPlease select:\n " // + "\"Backtracking without optimization\" algoritm for parser.", // "Warning", // javax.swing.JOptionPane.WARNING_MESSAGE); // fireParserEvent(new ParserMessageEvent(this, // "Thread - Parsing - was stopped.")); // return; // } // } this.ruleLayer = null; if (this.tmpPairs == null) { if (!checkIfReadyToTransform(this.pairsGraGra)) { return; } if (this.pOption.getSelectedParser() != ParserOption.SIMPLEPARSER) { if (this.pOption.layerEnabled()) { RuleLayer rlayer = new RuleLayer(this.pairsGraGra .getBasisGraGra().getEnabledRules()); //getListOfRules()); LayerGUI lg = new LayerGUI(this.parent, rlayer); lg.showGUI(); if (lg.isCancelled()) { this.pOption.enableLayer(false); this.pOptionGUI.update(); } else { this.ruleLayer = rlayer; this.pOption.enableLayer(true); this.pOptionGUI.update(); } } this.tmpPairs = ParserFactory.createEmptyCriticalPairs( this.pairsGraGra.getBasisGraGra(), this.cpOption); if (this.tmpPairs == null) { javax.swing.JOptionPane.showMessageDialog(null, "Generating of critical pairs is failed.", "Warning", javax.swing.JOptionPane.ERROR_MESSAGE); fireParserEvent(new ParserMessageEvent(this, "Thread - Parsing - was stopped.")); return; } this.generateCP = true; /* add PairEventListeners */ for (int i = 0; i < this.listener.size(); i++) { if (this.tmpPairs instanceof LayeredExcludePairContainer) ((LayeredExcludePairContainer) this.tmpPairs) .addPairEventListener(this.listener.elementAt(i)); else if (this.tmpPairs instanceof ExcludePairContainer) ((ExcludePairContainer) this.tmpPairs) .addPairEventListener(this.listener.elementAt(i)); } this.activeParser = true; fireParserEvent(new ParserMessageEvent(this, "Generate critical pairs. Please wait ...")); ParserFactory.generateCriticalPairs(this.tmpPairs); } // if( != ParserOption.SIMPLEPARSER ) else { // Backtracking without CP == ParserOption.SIMPLEPARSER this.generateCP = false; if (this.pOption.layerEnabled()) { this.ruleLayer = new RuleLayer(this.pairsGraGra.getBasisGraGra() .getListOfRules()); LayerGUI lg = new LayerGUI(this.parent, this.ruleLayer); lg.showGUI(); if (lg.isCancelled()) { this.pOption.enableLayer(false); this.pOptionGUI.update(); } else { this.pOption.enableLayer(true); this.pOptionGUI.update(); } } } if (this.option.getParserDisplay() != ParserGUIOption.PARSINGINVISIBLE) { if (!this.changer.isSet())// || !activeParser) this.changer.changeWith(this.parserDesktop.getComponent()); } } // end if(tmpPairs == null) else { this.generateCP = false; if (this.tmpPairs instanceof LayeredExcludePairContainer) { this.ruleLayer = new RuleLayer(this.tmpPairs.getGrammar() .getListOfRules()); this.pOption.enableLayer(true); this.pOptionGUI.update(); } if (this.option.getParserDisplay() != ParserGUIOption.PARSINGINVISIBLE) { if (!this.changer.isSet()) // || !activeParser) this.changer.changeWith(this.parserDesktop.getComponent()); } /* set pairs gragra */ if (this.pairsGraGra == null) this.pairsGraGra = new EdGraGra(this.tmpPairs.getGrammar()); else if (!this.pairsGraGra.getBasisGraGra().compareTo( this.tmpPairs.getGrammar())) { this.pairsGraGra = new EdGraGra(this.tmpPairs.getGrammar()); System.out .println("WARNING! The grammar loaded with critical pairs has some differences to the loaded stop grammar with parsing rules. The critical pairs grammar will be used for parsing."); } if (this.pairsGraGra == null || this.pairsGraGra.getBasisGraGra() == null) { javax.swing.JOptionPane.showMessageDialog(null, "Parsing rules are not exist.", "Warning", javax.swing.JOptionPane.ERROR_MESSAGE); fireParserEvent(new ParserMessageEvent(this, "Thread - Parser - was stopped.")); return; } } if (!checkIfReadyToTransform(this.hostGraphGrammar)) { return; } ((AttrTupleManager) AttrTupleManager.getDefaultManager()) .setVariableContext(false); // create parser OrdinaryMorphism om = this.hostGraphGrammar.getBasisGraGra().getGraph().isomorphicCopy(); if (om != null) this.excludeParser = ParserFactory.createParser( this.pairsGraGra.getBasisGraGra(), om.getImage(), this.stopGraphGrammar.getBasisGraGra().getGraph(), this.tmpPairs, this.pOption, this.ruleLayer); if (this.excludeParser == null) { javax.swing.JOptionPane.showMessageDialog(null, "Creating parser is failed.", "Warning", javax.swing.JOptionPane.ERROR_MESSAGE); fireParserEvent(new ParserMessageEvent(this, "Thread - Parsing - was stopped.")); return; } // set delay time of parsing this.excludeParser.setDelayAfterApplyRule(this.option .getDelayAfterApplyRule()); // add parser event listener for (int i = 0; i < this.listener.size(); i++) { if (this.excludeParser instanceof ExcludeParser) ((ExcludeParser) this.excludeParser) .addParserEventListener(this.listener.elementAt(i)); else if (this.excludeParser instanceof SimpleParser) ((SimpleParser) this.excludeParser) .addParserEventListener(this.listener.elementAt(i)); } this.parserDesktop.setLayout(this.hostGraphGrammar); this.parserDesktop.setStopLayout(this.stopGraphGrammar.getGraph()); this.parserDesktop.setParser(this.excludeParser, om); fireStatusMessageEvent(new StatusMessageEvent(this, "")); if (!this.generateCP) { fireParserEvent(new ParserMessageEvent(this, "Please choice menu - Parser / Start - to start parsing")); } this.activeParser = true; this.openP.setEnabled(false); this.startP.setEnabled(true); this.stopP.setEnabled(false); this.backP.setEnabled(true); } // end if(parserStartDialog.isReadyToParse()) } public void startParser() { if (this.generateCP) { fireParserEvent(new ParserMessageEvent(this, "Generating critical pairs ... Please wait.")); return; } this.openP.setEnabled(false); this.startP.setEnabled(false); this.stopP.setEnabled(true); this.backP.setEnabled(true); this.parserDesktop.hostFrameSetAnimationIcon(); fireParserEvent(new ParserMessageEvent(this, "Starting parser ...")); /* create parser thread and start parser */ Thread t = new Thread((Runnable) this.excludeParser); t.start(); } public void stopParser() { if (this.tmpPairs != null) ((ExcludePairContainer) this.tmpPairs).stop(); if (this.excludeParser instanceof ExcludeParser) ((ExcludeParser) this.excludeParser).stop(); else if (this.excludeParser instanceof SimpleParser) ((SimpleParser) this.excludeParser).stop(); this.startP.setEnabled(true); this.stopP.setEnabled(false); } public void backToGUI() { if (this.changer.isSet()) { this.changer.restore(); /* remove pair event listeners */ for (int i = 0; i < this.listener.size(); i++) { if (this.tmpPairs instanceof LayeredExcludePairContainer) { /* stop CP-Thread, if it is still running */ ((LayeredExcludePairContainer) this.tmpPairs).stop(); /* remove pair event listener */ ((LayeredExcludePairContainer) this.tmpPairs) .removePairEventListener(this.listener.elementAt(i)); } else if (this.tmpPairs instanceof ExcludePairContainer) { /* stop CP-Thread, if it is still running */ ((ExcludePairContainer) this.tmpPairs).stop(); /* remove pair event listener */ ((ExcludePairContainer) this.tmpPairs) .removePairEventListener(this.listener.elementAt(i)); } } /* remove parser event listeners */ for (int i = 0; i < this.listener.size(); i++) { if (this.excludeParser instanceof ExcludeParser) { /* stop P-Thread, if it is still running */ ((ExcludeParser) this.excludeParser).stop(); /* remove parser event listener */ ((ExcludeParser) this.excludeParser) .removeParserEventListener(this.listener.elementAt(i)); } else if (this.excludeParser instanceof SimpleParser) { /* stop P-Thread, if it is still running */ ((SimpleParser) this.excludeParser).stop(); /* remove parser event listener */ ((SimpleParser) this.excludeParser) .removeParserEventListener(this.listener.elementAt(i)); } } this.parserDesktop.disposeTestHostGraph(this.hostGraphGrammar); this.activeParser = false; this.openP.setEnabled(true); this.startP.setEnabled(false); this.stopP.setEnabled(false); this.backP.setEnabled(false); fireParserEvent(new ParserMessageEvent(this, "back to AGG editor")); } } private boolean checkIfReadyToTransform(EdGraGra gra) { Pair<Object, String> pair = gra.getBasisGraGra().isReadyToTransform(true); if (pair != null) { Object test = pair.first; if (test != null) { javax.swing.JOptionPane.showMessageDialog(null, "Parsing failed! \nGrammar \"" + gra.getName() + "\" is not OK.\n" + pair.second, "Warning", javax.swing.JOptionPane.ERROR_MESSAGE); fireParserEvent(new ParserMessageEvent(this, "Thread - Parsing - was stopped.")); return false; } } return true; } // -----------------------------------------------------------------------+ /** * Adds a StatusMessageListener. * * @param l * The listener. */ public void addStatusMessageListener(StatusMessageListener l) { if (!this.pmlistener.contains(l)) this.pmlistener.add(0, l); this.parserDesktop.addStatusMessageListener(l); } private void fireStatusMessageEvent(StatusMessageEvent e) { for (int i = 0; i < this.pmlistener.size(); i++) this.pmlistener.elementAt(i).newMessage(e); } /** * Adds a ParserEventListener. * * @param l * The listener. */ public void addParserEventListener(ParserEventListener l) { if (!this.listener.contains(l)) this.listener.add(0, l); } /** * Removes a ParserEventListener * * @param l * The listener. */ public void removeParserEventListener(ParserEventListener l) { if (this.listener.contains(l)) this.listener.removeElement(l); } /** * Sends a event to all its listeners. * * @param event * The event which will be sent */ private synchronized void fireParserEvent(ParserEvent e) { for (int i = 0; i < this.listener.size(); i++) { this.listener.elementAt(i).parserEventOccured(e); } } private final GUIExchange changer; private final ParserGUIOption option; private final ParserOptionGUI pOptionGUI; private final ParserOption pOption; private final LayerOptionGUI lOptionGUI; private final LayerOption lOption; private CriticalPairOption cpOption; private final ParserDesktop parserDesktop; private ParserDialog parserStartDialog; private Parser excludeParser; private PairContainer tmpPairs; private final JMenu menu; private final JMenuItem openP, startP, stopP, backP, options; private final Vector<ParserEventListener> listener; private final Vector<StatusMessageListener> pmlistener; private boolean activeParser; private boolean generateCP; private final agg.gui.AGGAppl parent; private EdGraGra pairsGraGra, hostGraphGrammar, stopGraphGrammar; private RuleLayer ruleLayer; private final agg.gui.treeview.GraGraTreeView treeView; private final Vector<JMenu> menus; }