package agg.parser; import java.util.Iterator; import java.util.Vector; import agg.xt_basis.BaseFactory; import agg.xt_basis.GraGra; import agg.xt_basis.Graph; import agg.xt_basis.GraphObject; import agg.xt_basis.Match; import agg.xt_basis.MorphCompletionStrategy; import agg.xt_basis.Morphism; import agg.xt_basis.Rule; import agg.xt_basis.StaticStep; import agg.xt_basis.TypeException; // ---------------------------------------------------------------------------+ /** * This parser eats graphs which are created by AGG. A parser needs a host graph * and a stop graph. The graph grammar for parsing must contain reducing rules. * This abstract parser provides some convenient methods for parsing. * * @author $Author: olga $ Parser Group * @version $Id: AbstractParser.java,v 1.15 2010/08/18 09:26:52 olga Exp $ */ public abstract class AbstractParser implements Parser { /** * The grammar which can recognize a graph */ protected GraGra grammar; /** * The Graph which will be parsed */ protected Graph graph; /** * The graph which stops the algorithm */ protected Graph stopGraph; /** * The set of critical pairs */ protected PairContainer pairContainer; /** * All listerner which want to receive events */ protected Vector<ParserEventListener> listener; protected int delay; /** * Creates a new abstract parser. This parser stores all the basic * information like host graph, stop graph, critical pairs and graph * grammar. * * @param grammar * The graph grammar. * @param hostGraph * The host graph. * @param stopGraph * The stop graph. * @param pairContainer * The container of the critical pairs. */ public AbstractParser(GraGra grammar, Graph hostGraph, Graph stopGraph, PairContainer pairContainer) { this.listener = new Vector<ParserEventListener>(); setHostGraph(hostGraph); setStopGraph(stopGraph); setGrammar(grammar); setCriticalPairs(pairContainer); } /** * Sets the host graph for the parser. * * @param hostGraph * The host graph. */ public void setHostGraph(Graph hostGraph) { this.graph = hostGraph; } /** * Sets the stop graph for the parser. * * @param stopGraph * The stop graph. */ public void setStopGraph(Graph stopGraph) { this.stopGraph = stopGraph; } /** * Sets the critical pairs for the parser. * * @param pairs * The critical pairs are holded in a container. */ public void setCriticalPairs(PairContainer pairs) { this.pairContainer = pairs; } /** * Sets the grammar for the parser. This grammar must contain reducing * rules. * * @param grammar * The grammar for the parser. */ public void setGrammar(GraGra grammar) { this.grammar = grammar; } /** * Returns the host graph from the parser. This method is important to get * the current state of parsing process. * * @return The current host graph. */ public Graph getHostGraph() { return this.graph; } /** * Returns the host graph from the parser. This method is important to get * the current state of parsing process. * * @return The current host graph. */ public Graph getGraph() { return getHostGraph(); } /** * Returns the current stop graph of the parser. * * @return The stop graph. */ public Graph getStopGraph() { return this.stopGraph; } // -----------------------------------------------------------------------+ /** * Starts the parser. The result is true if the parser can parse the graph * * @return true if the graph can be parsed. */ public abstract boolean parse(); /** * Applys a rule on a host graph. As the match provides access as well as to * the rule of the match as to the host graph. * * @param m * The match. */ protected boolean applyRule(Match m) { Morphism comatch = null; if (m.isValid()) { // TestStep s = new TestStep(); try { comatch = StaticStep.execute(m); ((agg.xt_basis.OrdinaryMorphism) comatch).dispose(); } catch (TypeException e) { fireParserEvent(new ParserErrorEvent(this, "Rule <" + m.getRule().getName() + "> cannot be applied")); return false; } fireParserEvent(new ParserMessageEvent(this, "Rule <" + m.getRule().getName() + "> is applied")); m.dispose(); } else { /* * dieser Fall sollte nie eintreten, da vor dem Aufruf von applyRule * der Match m ueberprueft werden sollte */ fireParserEvent(new ParserErrorEvent(this, "Rule <" + m.getRule().getName() + "> cannot be applied")); } return true; } // ----------------------------------------------------------------------+ /** * Finds a <B>valid</B> match for a set of rules. Additionally there is a * check on <CODE>RuleInstances</CODE>. * * @param g * The graph to match into. Usually the host graph. * @param rules * This enumeration must contain rule objects. * @param eri * The rule instances. * @return The valid match from a choosen rule into the graph. */ protected Match findMatch(Graph g, Iterator<?> rules, RuleInstances eri) { boolean found = false; Match resultMatch = null; while (rules.hasNext() && !found) { Rule rule = (Rule) rules.next(); resultMatch = BaseFactory.theFactory().createMatch(rule, g); resultMatch.setCompletionStrategy((MorphCompletionStrategy) this.grammar .getMorphismCompletionStrategy().clone(), true); while (!found && resultMatch.nextCompletion()) { if (resultMatch.isValid()) { if (eri != null) { if (!eri.isIn(resultMatch)) found = true; } else { found = true; } } } if (!found) { BaseFactory.theFactory().destroyMatch(resultMatch); resultMatch = null; } } return resultMatch; } // ----------------------------------------------------------------------+ /** * Finds a <B>valid</B> match for the given set of rules. * * @param g * the graph to match into. Usually the host graph. * @param rules * the rule set * @return * a valid match of an applicable rule of the set into the graph. */ protected Match findMatch(Graph g, Iterator<Rule> rules) { return findMatch(g, rules, null); } // ----------------------------------------------------------------------+ /** * Clears some internal stuff. */ protected void finalize() { getHostGraph().dispose(); } // ----------------------------------------------------------------------+ /** * Parse the methods and attributes of an UML-Diagram. */ public void parseString() { } // -----------------------------------------------------------------------+ /** * Adds a ParserEventListener. * * @param l * The listener. */ public void addParserEventListener(ParserEventListener l) { if (!this.listener.contains(l)) { this.listener.addElement(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 */ protected synchronized void fireParserEvent(ParserEvent event) { for (int i = 0; i < this.listener.size(); i++) { this.listener.elementAt(i).parserEventOccured(event); } } protected void printImageGraph(Morphism m) { System.out.println("Image graph of match: " + m); Graph left = m.getOriginal(); Iterator<?> e = left.getNodesSet().iterator(); while (e.hasNext()) { GraphObject o = (GraphObject) e.next(); GraphObject i = m.getImage(o); if (i != null) System.out.print(i); } e = left.getArcsSet().iterator(); while (e.hasNext()) { GraphObject o = (GraphObject) e.next(); GraphObject i = m.getImage(o); if (i != null) System.out.print(i); } System.out.println(); } protected void printGraph(Graph g) { System.out.println("Graph of match: "); Iterator<?> e = g.getNodesSet().iterator(); while (e.hasNext()) { GraphObject o = (GraphObject) e.next(); System.out.print(o); } e = g.getArcsSet().iterator(); while (e.hasNext()) { GraphObject o = (GraphObject) e.next(); System.out.print(o); } System.out.println(); } public void setDelayAfterApplyRule(int miliseconds) { this.delay = miliseconds; } } /* * End of Parser.java * ---------------------------------------------------------------------------- * $Log: AbstractParser.java,v $ * Revision 1.15 2010/08/18 09:26:52 olga * tuning * * Revision 1.14 2010/06/09 10:56:05 olga * tuning * * Revision 1.13 2010/05/05 16:17:01 olga * tuning * * Revision 1.12 2010/03/04 14:10:47 olga * code optimizing * * Revision 1.11 2010/02/22 15:01:21 olga * code optimizing * * Revision 1.10 2008/11/19 13:04:17 olga * Parser tuning * * Revision 1.9 2008/04/07 09:36:51 olga * Code tuning: refactoring + profiling * Extension: CPA - two new options added * * Revision 1.8 2007/11/01 09:58:18 olga * Code refactoring: generic types- done * * Revision 1.7 2007/10/22 09:03:16 olga * First implementation of CPA for grammars with node type inheritance. * Only for internal tests. * * Revision 1.6 2007/10/04 07:44:27 olga * Code tuning * * Revision 1.5 2007/09/24 09:42:38 olga * AGG transformation engine tuning * * Revision 1.4 2007/09/10 13:05:42 olga * In this update: * - package xerces2.5.0 is not used anymore; * - class com.objectspace.jgl.Pair is replaced by the agg own generic class agg.util.Pair; * - bugs fixed in: usage of PACs in rules; match completion; * usage of static method calls in attr. conditions * - graph editing: added some new features * Revision 1.3 2007/06/13 08:32:56 olga Update: * V161 * * Revision 1.2 2007/04/11 10:03:36 olga Undo, Redo tuning, Simple Parser- bug * fixed * * Revision 1.1 2005/08/25 11:56:57 enrico *** empty log message *** * * Revision 1.1 2005/05/30 12:58:03 olga Version with Eclipse * * Revision 1.8 2004/04/15 10:49:48 olga Kommentare * * Revision 1.7 2004/01/28 17:58:38 olga Errors suche * * Revision 1.6 2004/01/22 17:51:18 olga tests * * Revision 1.5 2003/03/05 18:24:09 komm sorted/optimized import statements * * Revision 1.4 2003/01/20 12:11:46 olga Tests raus * * Revision 1.3 2002/11/11 10:43:25 komm added support for multiplicity check * * Revision 1.2 2002/09/19 16:20:15 olga Nur Testausgaben weg. * * Revision 1.1.1.1 2002/07/11 12:17:23 olga Imported sources * * Revision 1.3 2001/09/24 16:41:33 olga * * Arbeit an LayerFunction und LayeredParser. * * Revision 1.2 2001/03/08 10:44:50 olga Neue Files aus parser branch in Head * eingefuegt. * * Revision 1.1.2.3 2001/01/28 13:14:50 shultzke API fertig * * Revision 1.1.2.2 2001/01/01 21:24:31 shultzke alle Parser fertig inklusive * Layout * * Revision 1.1.2.1 2000/12/04 12:26:46 shultzke drei parser stehen zur * verfuegung * */