ComplexPatternElement.java |
1 /* 2 * ComplexPatternElement.java - transducer class 3 * 4 * Copyright (c) 1998-2005, The University of Sheffield. 5 * 6 * This file is part of GATE (see http://gate.ac.uk/), and is free 7 * software, licenced under the GNU Library General Public License, 8 * Version 2, June 1991 (in the distribution as file licence.html, 9 * and also available at http://gate.ac.uk/gate/licence.html). 10 * 11 * Hamish Cunningham, 24/07/98 12 * 13 * $Id: ComplexPatternElement.java,v 1.11 2005/01/11 13:51:36 ian Exp $ 14 */ 15 16 17 package gate.jape; 18 19 import java.util.Iterator; 20 21 import gate.AnnotationSet; 22 import gate.Document; 23 import gate.util.Strings; 24 25 26 /** 27 * A pattern element enclosed in round brackets. Has a 28 * ConstraintGroups, Kleene operator and binding name. 29 */ 30 public class ComplexPatternElement extends PatternElement 31 implements JapeConstants, java.io.Serializable 32 { 33 /** Debug flag */ 34 private static final boolean DEBUG = false; 35 36 /** Kleene operator (defaults to none). Other values: KLEENE_STAR (*); 37 * KLEENE_PLUS (+); KLEENE_QUERY (?) */ 38 private int kleeneOp = NO_KLEENE_OP; 39 40 /** Binding name (may be null). */ 41 private String bindingName = null; 42 43 /** Get binding name. */ 44 public String getBindingName() { return bindingName; } 45 46 /** Get a list of CPEs that we contain. */ 47 protected Iterator getCPEs() { 48 return constraintGroup.getCPEs(); 49 } // getCPEs 50 51 /** The recursive definition of what pattern elements make up this one. */ 52 private ConstraintGroup constraintGroup; 53 54 /** Construction from ConstraintGroup, Kleene operator type and binding 55 * name. Kleene types are defined in JapeConstants. 56 */ 57 public ComplexPatternElement( 58 ConstraintGroup constraintGroup, 59 int kleeneOp, 60 String bindingName 61 ) { 62 this.constraintGroup = constraintGroup; 63 this.kleeneOp = kleeneOp; 64 this.bindingName = bindingName; 65 } 66 67 /** Need cloning for processing of macro references. See comments on 68 * <CODE>PatternElement.clone()</CODE> 69 */ 70 public Object clone() { 71 ComplexPatternElement newPE = (ComplexPatternElement) super.clone(); 72 newPE.constraintGroup = (ConstraintGroup) constraintGroup.clone(); 73 return newPE; 74 } // clone 75 76 /** Finish: replace dynamic data structures with Java arrays; called 77 * after parsing. 78 */ 79 public void finish() { 80 constraintGroup.finish(); 81 } // finish 82 83 /** Access to the annotations that have been matched. */ 84 public AnnotationSet getMatchedAnnots() { 85 return constraintGroup.getMatchedAnnots(); 86 } 87 88 /** Reset: clear caches of annotations matched. */ 89 public void reset() { 90 constraintGroup.reset(); 91 super.reset(); 92 } // reset 93 94 /** Multilevel rollback of annotation caches. */ 95 public void rollback(int arity) { 96 /*Debug.pr( 97 this, "CPE rollback(" + arity + "), mH.size = " + 98 matchHistory.size() + Debug.getNl() 99 );*/ 100 101 // for arity times, pop the arity history stack and 102 // ask the CG to rollback how ever many times it succeeded then 103 for(int i=0; i<arity; i++) { 104 int matchArity = ((Integer) matchHistory.pop()).intValue(); 105 constraintGroup.rollback(matchArity); 106 } 107 } // rollback 108 109 /** Does this element match the document at this position? */ 110 public boolean matches( 111 Document doc, int position, MutableInteger newPosition 112 ) { 113 /*Debug.pr( 114 this, "CPE.matches: trying at position " + position + Debug.getNl() 115 );*/ 116 int matchArity = 0; // number of successful applications in this match 117 boolean firstTry = constraintGroup.matches(doc, position, newPosition); 118 if(firstTry) { 119 matchArity++; 120 /*Debug.pr(this, 121 "CPE.matches: first try succeeded, newPosition = " + newPosition.value 122 + Debug.getNl() 123 );*/ 124 } 125 int theEndOfTheDocument = doc.getContent().size().intValue(); 126 127 if(kleeneOp == NO_KLEENE_OP) { 128 if(firstTry) matchHistory.push(new Integer(matchArity)); 129 return firstTry; 130 } 131 else if(kleeneOp == KLEENE_QUERY) { 132 if(firstTry) matchHistory.push(new Integer(matchArity)); 133 /* Debug.pr(this, "CPE.matches: true, QUERY rule"); */ 134 return true; 135 } 136 else if(kleeneOp == KLEENE_PLUS) { 137 if(! firstTry) 138 return false; // no cache purge: maybe we're under another * etc. 139 } 140 else if(kleeneOp == KLEENE_STAR && !firstTry) { 141 /*Debug.pr(this, 142 "CPE.matches: true, STAR rule, newPos("+newPosition.value+")");*/ 143 matchHistory.push(new Integer(matchArity)); 144 return true; 145 } 146 147 // we get here if we have either Kleene *, or Kleene +, and a 148 // successful first move. now we try it again as many times as it 149 // succeeds, store the final match arity and then return true 150 while(constraintGroup.matches(doc, newPosition.value, newPosition)) { 151 /*Debug.pr(this, 152 "CPE.matches: trying while loop, matchArity = " + matchArity);*/ 153 matchArity++; 154 155 // if we've negated failing constraints, we may match for ever 156 if(newPosition.value >= theEndOfTheDocument) // stop at the end! 157 break; 158 } // while 159 matchHistory.push(new Integer(matchArity)); 160 //Debug.pr(this, 161 // "CPE.matches: true, matchArity(" + matchArity + ") pushed"); 162 return true; 163 } // matches 164 165 166 /** Create a string representation of the object. */ 167 public String toString() { return toString(""); } 168 169 /** Create a string representation of the object. */ 170 public String toString(String pad) { 171 String newline = Strings.getNl(); 172 173 StringBuffer buf = new StringBuffer( 174 pad + "CPE: bindingName(" + bindingName + "); kleeneOp(" 175 ); 176 177 switch(kleeneOp) { 178 case NO_KLEENE_OP: buf.append("NO_KLEENE_OP"); break; 179 case KLEENE_STAR: buf.append("KLEENE_STAR"); break; 180 case KLEENE_QUERY: buf.append("KLEENE_QUERY"); break; 181 case KLEENE_PLUS: buf.append("KLEENE_PLUS"); break; 182 default: break; 183 } 184 185 buf.append( 186 "); constraintGroup(" + newline + 187 constraintGroup.toString(Strings.addPadding(pad, INDENT_PADDING)) + 188 newline + pad + ") CPE." + newline 189 ); 190 191 return buf.toString(); 192 } // toString 193 //needed by FSM 194 195 public int getKleeneOp(){ return kleeneOp; }; 196 197 public ConstraintGroup getConstraintGroup(){ return constraintGroup; }; 198 199 } // class ComplexPatternElement 200 201 202 // $Log: ComplexPatternElement.java,v $ 203 // Revision 1.11 2005/01/11 13:51:36 ian 204 // Updating copyrights to 1998-2005 in preparation for v3.0 205 // 206 // Revision 1.10 2004/07/21 17:10:07 akshay 207 // Changed copyright from 1998-2001 to 1998-2004 208 // 209 // Revision 1.9 2004/03/25 13:01:15 valyt 210 // Imports optimisation throughout the Java sources 211 // (to get rid of annoying warnings in Eclipse) 212 // 213 // Revision 1.8 2001/09/13 12:09:49 kalina 214 // Removed completely the use of jgl.objectspace.Array and such. 215 // Instead all sources now use the new Collections, typically ArrayList. 216 // I ran the tests and I ran some documents and compared with keys. 217 // JAPE seems to work well (that's where it all was). If there are problems 218 // maybe look at those new structures first. 219 // 220 // Revision 1.7 2001/09/12 11:59:33 kalina 221 // Changed the old JAPE stuff to use the new Collections API, 222 // instead of com.objectspace stuff. Will eliminate that library 223 // completely very soon! Just one class left to re-implement, 224 // 225 // ParseCPSL.jj changed accordingly. All tested and no smoke. 226 // 227 // Revision 1.6 2000/11/08 16:35:02 hamish 228 // formatting 229 // 230 // Revision 1.5 2000/10/26 10:45:30 oana 231 // Modified in the code style 232 // 233 // Revision 1.4 2000/10/16 16:44:33 oana 234 // Changed the comment of DEBUG variable 235 // 236 // Revision 1.3 2000/10/10 15:36:35 oana 237 // Changed System.out in Out and System.err in Err; 238 // Added the DEBUG variable seted on false; 239 // Added in the header the licence; 240 // 241 // Revision 1.2 2000/04/14 18:02:46 valyt 242 // Added some gate.fsm classes 243 // added some accessor function in old jape classes 244 // 245 // Revision 1.1 2000/02/23 13:46:05 hamish 246 // added 247 // 248 // Revision 1.1.1.1 1999/02/03 16:23:01 hamish 249 // added gate2 250 // 251 // Revision 1.14 1998/11/13 13:17:16 hamish 252 // merged in the doc length bug fix 253 // 254 // Revision 1.13 1998/11/12 17:47:27 kalina 255 // A bug fixed, wasn't restoring the document length 256 // 257 // Revision 1.12 1998/11/05 13:36:29 kalina 258 // moved to use array of JdmAttributes for selectNextAnnotation instead 259 // of a sequence 260 // 261 // Revision 1.11 1998/11/01 21:21:35 hamish 262 // use Java arrays in transduction where possible 263 // 264 // Revision 1.10 1998/10/06 16:16:09 hamish 265 // negation percolation during constrain add; position advance when none at end 266 // 267 // Revision 1.9 1998/10/01 16:06:29 hamish 268 // new appelt transduction style, replacing buggy version 269 // 270 // Revision 1.8 1998/09/26 09:19:14 hamish 271 // added cloning of PE macros 272 // 273 // Revision 1.7 1998/09/17 16:48:29 hamish 274 // added macro defs and macro refs on LHS 275 // 276 // Revision 1.6 1998/08/12 15:39:32 hamish 277 // added padding toString methods 278 // 279 // Revision 1.5 1998/08/05 21:58:04 hamish 280 // backend works on simple test 281 // 282 // Revision 1.4 1998/08/03 19:51:19 hamish 283 // rollback added 284 // 285 // Revision 1.3 1998/07/30 11:05:14 hamish 286 // more jape 287 // 288 // Revision 1.2 1998/07/29 11:06:54 hamish 289 // first compiling version 290 // 291 // Revision 1.1.1.1 1998/07/28 16:37:46 hamish 292 // gate2 lives 293