|
RightHandSide |
|
1 /* 2 * RightHandSide.java - transducer class 3 * 4 * Copyright (c) 1998-2001, 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: RightHandSide.java,v 1.24 2002/02/27 15:11:16 valyt Exp $ 14 */ 15 16 17 package gate.jape; 18 19 import java.util.*; 20 import java.io.*; 21 import java.lang.reflect.Constructor; 22 import java.lang.reflect.Method; 23 24 25 import gate.annotation.*; 26 import gate.util.*; 27 import gate.*; 28 29 30 /** 31 * The RHS of a CPSL rule. The action part. Contains an inner class 32 * created from the code in the grammar RHS. 33 */ 34 public class RightHandSide implements JapeConstants, java.io.Serializable 35 { 36 /** Debug flag */ 37 private static final boolean DEBUG = false; 38 39 /** An instance of theActionClass. */ 40 transient private Object theActionObject; 41 42 /** The string we use to create the action class. */ 43 private StringBuffer actionClassString; 44 45 /** The bytes of the compiled action class. */ 46 private byte[] actionClassBytes; 47 48 /** The name of the action class. */ 49 private String actionClassName; 50 51 /** Package name for action classes. It's called a "dir name" because 52 * we used to dump the action classes to disk and compile them there. 53 */ 54 static private String actionsDirName = "japeactionclasses"; 55 56 /** The qualified name of the action class. */ 57 private String actionClassQualifiedName; 58 59 /** Name of the .java file for the action class. */ 60 private String actionClassJavaFileName; 61 62 /** Name of the .class file for the action class. */ 63 private String actionClassClassFileName; 64 65 /** Cardinality of the action class set. Used for ensuring class name 66 * uniqueness. 67 */ 68 private static int actionClassNumber = 0; 69 70 /** Allow setting of the initial action class number. Used for ensuring 71 * class name uniqueness when running more than one transducer. The 72 * long-term solution is to have separate class loaders for each 73 * transducer. 74 */ 75 public static void setActionClassNumber(int n) { actionClassNumber = n; } 76 77 /** The set of block names. 78 * Used to ensure we only get their annotations once in the action class. 79 */ 80 private HashSet blockNames; 81 82 /** Returns the string for the java code */ 83 public String getActionClassString() { return actionClassString.toString(); } 84 85 public String getActionClassName() { return actionClassQualifiedName; } 86 87 /** The LHS of our rule, where we get bindings from. */ 88 private LeftHandSide lhs; 89 90 /** A list of the files and directories we create. */ 91 static private ArrayList tempFiles = new ArrayList(); 92 93 /** Local fashion for newlines. */ 94 private final String nl = Strings.getNl(); 95 96 /** Debug flag. */ 97 static final boolean debug = false; 98 private String phaseName; 99 private String ruleName; 100 101 /** Construction from the transducer name, rule name and the LHS. */ 102 public RightHandSide( 103 String transducerName, String ruleName, LeftHandSide lhs 104 ) { 105 // debug = true; 106 this.lhs = lhs; 107 this.phaseName = transducerName; 108 this.ruleName = ruleName; 109 actionClassName = new String( 110 transducerName + ruleName + "ActionClass" + actionClassNumber++ 111 ); 112 blockNames = new HashSet(); 113 114 // initialise the class action string 115 actionClassString = new StringBuffer( 116 "// " + actionClassName + nl + 117 "package " + actionsDirName + "; " + nl + 118 "import java.io.*;" + nl + 119 "import java.util.*;" + nl + 120 "import gate.*;" + nl + 121 "import gate.jape.*;" + nl + 122 "import gate.annotation.*;" + nl + 123 "import gate.util.*;" + nl + nl + 124 "public class " + actionClassName + nl + 125 "implements java.io.Serializable, RhsAction { " + nl + 126 " public void doit(Document doc, java.util.Map bindings, " + nl + 127 " AnnotationSet annotations, " + nl + 128 " AnnotationSet inputAS, AnnotationSet outputAS) {" + nl 129 ); 130 131 // initialise various names 132 actionClassJavaFileName = 133 actionsDirName + File.separator + 134 actionClassName.replace('.', File.separatorChar) + ".java"; 135 actionClassQualifiedName = 136 actionsDirName. 137 replace(File.separatorChar, '.').replace('/', '.').replace('\\', '.') + 138 "." + actionClassName; 139 actionClassClassFileName = 140 actionClassQualifiedName.replace('.', File.separatorChar) + ".class"; 141 } // Construction from lhs 142 143 /** Add an anonymous block to the action class */ 144 public void addBlock(String anonymousBlock) { 145 actionClassString.append(anonymousBlock); 146 actionClassString.append(nl); 147 } // addBlock(anon) 148 149 /** Add a named block to the action class */ 150 public void addBlock(String name, String namedBlock) { 151 // is it really a named block? 152 // (dealing with null name cuts code in the parser...) 153 if(name == null) { 154 addBlock(namedBlock); 155 return; 156 } 157 158 if(blockNames.add(name)) // it wasn't already a member 159 actionClassString.append( 160 " AnnotationSet " + name + "Annots = (AnnotationSet)bindings.get(\"" 161 + name + "\"); " + nl 162 ); 163 164 actionClassString.append( 165 " if(" + name + "Annots != null && " + name + 166 "Annots.size() != 0) { " + nl + " " + namedBlock + 167 nl + " }" + nl 168 ); 169 } // addBlock(name, block) 170 171 /** Create the action class and an instance of it. */ 172 public void createActionClass() throws JapeException { 173 // terminate the class string 174 actionClassString.append(" }" + nl + "}" + nl); 175 // try { 176 // Javac.loadClass(actionClassString.toString(), 177 // actionClassJavaFileName); 178 // } catch(GateException e) { 179 // String nl = Strings.getNl(); 180 // String actionWithNumbers = 181 // Strings.addLineNumbers(actionClassString.toString()); 182 // throw new JapeException( 183 // "Couldn't create action class: " + nl + e + nl + 184 // "offending code was: " + nl + actionWithNumbers + nl 185 // ); 186 // } 187 // instantiateActionClass(); 188 } // createActionClass 189 190 /** Create an instance of the action class. */ 191 public void instantiateActionClass() throws JapeException { 192 193 try { 194 theActionObject = Gate.getClassLoader(). 195 loadClass(actionClassQualifiedName). 196 newInstance(); 197 } catch(Exception e) { 198 throw new JapeException( 199 "couldn't create instance of action class " + actionClassName + ": " 200 + e.getMessage() 201 ); 202 } 203 } // instantiateActionClass 204 205 /** Remove class files created for actions. */ 206 public static void cleanUp() { 207 if(tempFiles.size() == 0) return; 208 209 // traverse the list in reverse order, coz any directories we 210 // created were done first 211 for(ListIterator i = tempFiles.listIterator(tempFiles.size()-1); 212 i.hasPrevious(); 213 ) { 214 File tempFile = (File) i.previous(); 215 tempFile.delete(); 216 } // for each tempFile 217 218 tempFiles.clear(); 219 } // cleanUp 220 221 222 /** Makes changes to the document, using LHS bindings. */ 223 public void transduce(Document doc, java.util.Map bindings, 224 AnnotationSet inputAS, AnnotationSet outputAS) 225 throws JapeException { 226 if(theActionObject == null) { 227 instantiateActionClass(); 228 } 229 230 // run the action class 231 try { 232 ((RhsAction) theActionObject).doit(doc, bindings, outputAS, 233 inputAS, outputAS); 234 235 // if the action class throws an exception, re-throw it with a 236 // full description of the problem, inc. stack trace and the RHS 237 // action class code 238 } catch (Exception e) { 239 StringWriter stackTraceWriter = new StringWriter(); 240 e.printStackTrace(new PrintWriter(stackTraceWriter)); 241 throw new JapeException( 242 "Couldn't run RHS action: " + Strings.getNl() + 243 stackTraceWriter.getBuffer().toString() + 244 Strings.addLineNumbers(actionClassString.toString()) 245 ); 246 } 247 } // transduce 248 249 /** Create a string representation of the object. */ 250 public String toString() { return toString(""); } 251 252 /** Create a string representation of the object. */ 253 public String toString(String pad) { 254 String nl = Strings.getNl(); 255 StringBuffer buf = new StringBuffer( 256 pad + "RHS: actionClassName(" + actionClassName + "); " 257 ); 258 //buf.append("actionClassString(" + nl + actionClassString + nl); 259 buf.append( 260 "actionClassClassFileName(" + nl + actionClassClassFileName + nl 261 ); 262 buf.append("actionClassJavaFileName(" + nl + actionClassJavaFileName + nl); 263 buf.append( 264 "actionClassQualifiedName(" + nl + actionClassQualifiedName + nl 265 ); 266 267 buf.append("blockNames(" + blockNames.toString() + "); "); 268 269 buf.append(nl + pad + ") RHS." + nl); 270 271 return buf.toString(); 272 } // toString 273 274 /** Create a string representation of the object. */ 275 public String shortDesc() { 276 String res = "" + actionClassName; 277 return res; 278 } 279 public void setPhaseName(String phaseName) { 280 this.phaseName = phaseName; 281 } 282 public String getPhaseName() { 283 return phaseName; 284 } 285 public void setRuleName(String ruleName) { 286 this.ruleName = ruleName; 287 } 288 public String getRuleName() { 289 return ruleName; 290 } // toString 291 292 } // class RightHandSide 293 294 295 // $Log: RightHandSide.java,v $ 296 // Revision 1.24 2002/02/27 15:11:16 valyt 297 // 298 // bug 00011: 299 // Jape access to InputAS 300 // 301 // Revision 1.23 2002/02/26 13:27:12 valyt 302 // 303 // Error messages from the compiler 304 // 305 // Revision 1.22 2002/02/26 10:30:07 valyt 306 // 307 // new compile solution 308 // 309 // Revision 1.21 2002/02/12 11:39:03 valyt 310 // 311 // removed sate and status members for Jape generated classes 312 // 313 // Revision 1.20 2002/02/04 13:59:04 hamish 314 // added status and state members to RhsAction 315 // 316 // Revision 1.19 2001/11/16 13:03:35 hamish 317 // moved line numbers method to Strings 318 // 319 // Revision 1.18 2001/11/16 10:29:45 hamish 320 // JAPE RHS compiler errors now include the RHS code; test added 321 // 322 // Revision 1.17 2001/11/15 14:05:09 hamish 323 // better error messages from JAPE RHS problems 324 // 325 // Revision 1.16 2001/11/01 15:49:09 valyt 326 // 327 // DEBUG mode for Japes 328 // 329 // Revision 1.15 2001/09/13 12:09:50 kalina 330 // Removed completely the use of jgl.objectspace.Array and such. 331 // Instead all sources now use the new Collections, typically ArrayList. 332 // I ran the tests and I ran some documents and compared with keys. 333 // JAPE seems to work well (that's where it all was). If there are problems 334 // maybe look at those new structures first. 335 // 336 // Revision 1.14 2000/11/08 16:35:03 hamish 337 // formatting 338 // 339 // Revision 1.13 2000/10/26 10:45:30 oana 340 // Modified in the code style 341 // 342 // Revision 1.12 2000/10/16 16:44:34 oana 343 // Changed the comment of DEBUG variable 344 // 345 // Revision 1.11 2000/10/10 15:36:36 oana 346 // Changed System.out in Out and System.err in Err; 347 // Added the DEBUG variable seted on false; 348 // Added in the header the licence; 349 // 350 // Revision 1.10 2000/07/04 14:37:39 valyt 351 // Added some support for Jape-ing in a different annotations et than the default one; 352 // Changed the L&F for the JapeGUI to the System default 353 // 354 // Revision 1.9 2000/06/12 13:33:27 hamish 355 // removed japeactionclasse create code (static init block 356 // 357 // Revision 1.8 2000/05/16 10:38:25 hamish 358 // removed printout 359 // 360 // Revision 1.7 2000/05/16 10:30:33 hamish 361 // uses new gate.util.Jdk compiler 362 // 363 // Revision 1.6 2000/05/05 12:51:12 valyt 364 // Got rid of deprecation warnings 365 // 366 // Revision 1.5 2000/05/05 10:14:09 hamish 367 // added more to toString 368 // 369 // Revision 1.4 2000/05/02 16:54:47 hamish 370 // porting to new annotation API 371 // 372 // Revision 1.3 2000/04/20 13:26:42 valyt 373 // Added the graph_drawing library. 374 // Creating of the NFSM and DFSM now works. 375 // 376 // Revision 1.2 2000/02/24 17:28:48 hamish 377 // more porting to new API 378 // 379 // Revision 1.1 2000/02/23 13:46:11 hamish 380 // added 381 // 382 // Revision 1.1.1.1 1999/02/03 16:23:02 hamish 383 // added gate2 384 // 385 // Revision 1.21 1998/11/13 17:25:10 hamish 386 // stop it using sun.tools... when in 1.2 387 // 388 // Revision 1.20 1998/10/30 15:31:07 kalina 389 // Made small changes to make compile under 1.2 and 1.1.x 390 // 391 // Revision 1.19 1998/10/29 12:17:12 hamish 392 // use reflection when using sun compiler classes, so can compile without them 393 // 394 // Revision 1.18 1998/10/01 16:06:36 hamish 395 // new appelt transduction style, replacing buggy version 396 // 397 // Revision 1.17 1998/09/18 16:54:17 hamish 398 // save/restore works except for attribute seq 399 // 400 // Revision 1.16 1998/09/18 13:35:44 hamish 401 // refactored to split up createActionClass 402 // 403 // Revision 1.15 1998/09/18 12:15:40 hamish 404 // bugs fixed: anon block null ptr; no error for some non-existant labelled blocks 405 // 406 // Revision 1.14 1998/08/19 20:21:41 hamish 407 // new RHS assignment expression stuff added 408 // 409 // Revision 1.13 1998/08/17 10:43:29 hamish 410 // action classes have unique names so can be reloaded 411 // 412 // Revision 1.12 1998/08/12 15:39:42 hamish 413 // added padding toString methods 414 // 415 // Revision 1.11 1998/08/10 14:16:38 hamish 416 // fixed consumeblock bug and added batch.java 417 // 418 // Revision 1.10 1998/08/07 12:01:46 hamish 419 // parser works; adding link to backend 420 // 421 // Revision 1.9 1998/08/05 21:58:07 hamish 422 // backend works on simple test 423 // 424 // Revision 1.8 1998/08/04 12:42:56 hamish 425 // fixed annots null check bug 426 // 427 // Revision 1.7 1998/08/03 21:44:57 hamish 428 // moved parser classes to gate.jape.parser 429 // 430 // Revision 1.6 1998/08/03 19:51:26 hamish 431 // rollback added 432 // 433 // Revision 1.5 1998/07/31 16:50:18 hamish 434 // RHS compilation works; it runs - and falls over... 435 // 436 // Revision 1.4 1998/07/31 13:12:25 hamish 437 // done RHS stuff, not tested 438 // 439 // Revision 1.3 1998/07/30 11:05:24 hamish 440 // more jape 441 // 442 // Revision 1.2 1998/07/29 11:07:10 hamish 443 // first compiling version 444 // 445 // Revision 1.1.1.1 1998/07/28 16:37:46 hamish 446 // gate2 lives 447
|
RightHandSide |
|