/* * Rule.java - transducer class * * Copyright (c) 1998-2001, The University of Sheffield. * * This file is part of GATE (see http://gate.ac.uk/), and is free * software, licenced under the GNU Library General Public License, * Version 2, June 1991 (in the distribution as file licence.html, * and also available at http://gate.ac.uk/gate/licence.html). * * Hamish Cunningham, 24/07/98 * * Minor modifications made by Luc Plamondon, Universit� de Montr�al, 27/11/03: * - migrated original file from gate.jape to * ca.umontreal.iro.rali.gate.jape package. * * $Id$ */ package ca.umontreal.iro.rali.gate.jape; import java.util.*; import gate.annotation.*; import gate.event.*; import gate.util.*; import gate.*; /** * A CPSL rule. Has an LHS, RHS and a name, and a priority. */ public class Rule extends Transducer implements JapeConstants, java.io.Serializable { /** Debug flag */ private static final boolean DEBUG = false; /** Construction */ public Rule( String name, int position, int priority, LeftHandSide lhs, RightHandSide rhs ) { this.name = name; this.position = position; this.priority = priority; this.lhs = lhs; this.rhs = rhs; } // Construction /** The LHS or pattern of the rule. */ private LeftHandSide lhs; /** The RHS or action of the rule. */ private RightHandSide rhs; /** The priority of the rule. */ private int priority; /** Get the rule priority. */ public int getPriority() { return priority; } /** The rule's position in sequence (e.g. order in file). */ private int position; /** Get the rule's position in sequence (e.g. order in file). */ public int getPosition() { return position; } /** If we're pending (have matched), get the position we want to fire in, * else -1. */ public int pending() { return pendingPosition; } // pending /** If we matched but didn't fire yet, this is our pending position. */ private int pendingPosition = -1; /** Flag for end of document during getNextMatch. */ private boolean weFinished = false; /** Have we hit the end of the document without matching? */ public boolean finished() { return weFinished; } // finished /** Finish: replace dynamic data structures with Java arrays; called * after parsing. WARNING: * bad choice of names: this is not related to the weFinished * member or the finished method! */ public void finish() { lhs.finish(); } // finish /** If another match at or beyond <CODE>position</CODE> is possible return * the position we want to fire in, else -1. */ public int getNextMatch(Document doc, int position, int end) { MutableInteger newPosition = new MutableInteger(); newPosition.value = position; while(position < end) { if(matches(doc, position, newPosition)) { pendingPosition = getStartPosition(); return pendingPosition; } position = Math.max(position + 1, newPosition.value); } // while position not final weFinished = true; return -1; } // getNextMatch /** Return the ending position of a match. This is the rightmost span * end of the matched annotations. */ public int getEndPosition() { return lhs.getMatchedAnnots().lastNode().getOffset().intValue(); } /** Return the starting position of a match. This is the leftmost span * start of the matched annotations. */ public int getStartPosition() { return lhs.getMatchedAnnots().firstNode().getOffset().intValue(); } /** Does this element match the document at this position? */ public boolean matches( Document doc, int position, MutableInteger newPosition ) { if(DEBUG) Out.println("trying rule " + name + " at " + position); return lhs.matches(doc, position, newPosition); } // matches /** Apply the RHS of this rule (LHS must have been matched first). */ public void transduce(Document doc, AnnotationSet inputAS, AnnotationSet outputAS) throws JapeException { // the righthand side does the transduction, using bindings from lhs */ if(DEBUG) Out.println("applying rule " + name); // rhs.transduce(doc); /*Debug.pr( this, "Rule.transduce: annotations after transduction: " + doc.selectAnnotations("Name", new FeatureMap()).toString() + Debug.getNl() );*/ // clear the caches of matched annotations in the LHS reset(); //Debug.pr(this, "LHS after reset: " + lhs.toString()); } // transduce /** Clear away the results of a match. */ public void reset() { if(weFinished) // no annotations cached weFinished = false; else lhs.reset(); pendingPosition = -1; } /** For debugging. */ // public String getName() { return name; } /** Clean up (delete action class files, for e.g.). */ public void cleanUp() { rhs.cleanUp(); } // cleanUp /** Create a string representation of the object. */ public String toString() { return toString(""); } /** Create a string representation of the object. */ public String toString(String pad) { String newline = Strings.getNl(); String newPad = Strings.addPadding(pad, INDENT_PADDING); StringBuffer buf = new StringBuffer( pad + "Rule: name(" + name + "); position(" + position + "); priority(" + priority + "); pendingPosition(" + pendingPosition + "); " + "weFinished(" + weFinished + "); lhs(" + newline + lhs.toString(newPad) + newline + pad + "); rhs(" + newline + rhs.toString(newPad) + newline + pad + ");" ); buf.append(newline + pad + ") Rule." + newline); return buf.toString(); } // toString //needed by FSM public LeftHandSide getLHS(){ return lhs; } public RightHandSide getRHS(){ return rhs; } //StatusReporter VOID Implementation public void addStatusListener(StatusListener listener){} public void removeStatusListener(StatusListener listener){} //ProcessProgressReporter VOID implementation public void addProcessProgressListener(ProgressListener listener){} public void removeProcessProgressListener(ProgressListener listener){} //ProcessProgressReporter implementation ends here } // class Rule