1
15
16
17 package gate.jape;
18
19 import java.util.*;
20
21 import gate.*;
22 import gate.annotation.AnnotationSetImpl;
23 import gate.creole.ExecutionException;
24 import gate.creole.ExecutionInterruptedException;
25 import gate.event.ProgressListener;
26 import gate.fsm.*;
27 import gate.util.*;
28
29 import debugger.resources.pr.TraceContainer;
31 import debugger.resources.pr.RuleTrace;
32 import debugger.resources.SPTLock;
33 import debugger.resources.PhaseController;
34
36
42 public class SinglePhaseTransducer
43 extends Transducer implements JapeConstants, java.io.Serializable
44 {
45
46 private static final boolean DEBUG = false;
47
48 PhaseController phaseController = null;
50 TraceContainer rulesTrace = null;
51 RuleTrace currRuleTrace = null;
52
53 public PhaseController getPhaseController() {
54 return phaseController;
55 }
56
57 public void setPhaseController(PhaseController phaseController) {
58 this.phaseController = phaseController;
59 }
60
62
63
64 public SinglePhaseTransducer(String name) {
65 this.name = name;
66 rules = new PrioritisedRuleList();
67 finishedAlready = false;
68 }
70
71 private int ruleApplicationStyle = BRILL_STYLE;
72
73
74 public void setRuleApplicationStyle(int style) {
75 ruleApplicationStyle = style;
76 }
77
78
82 private PrioritisedRuleList rules;
83
84 FSM fsm;
85
86 public FSM getFSM(){
87 return fsm;
88 }
89
90
91 public void addRule(Rule rule) {
92 rules.add(rule);
93 }
95
96 private java.util.HashMap optionSettings = new java.util.HashMap();
97
98
101 public void setOption(String name, String setting) {
102 optionSettings.put(name, setting);
103 }
105
106 public String getOption(String name) {
107 return (String) optionSettings.get(name);
108 }
110
111 private boolean finishedAlready;
112
113
116 public void finish() {
117 if (finishedAlready)
119 return;
120 else
121 finishedAlready = true;
122
123 Map actionClasses = new HashMap(rules.size());
126 for (Iterator i = rules.iterator(); i.hasNext(); ) {
127 Rule rule = (Rule) i.next();
128 rule.finish();
129 actionClasses.put(rule.getRHS().getActionClassName(),
130 rule.getRHS().getActionClassString());
131 }
132 try{
133 gate.util.Javac.loadClasses(actionClasses);
134 }catch(Exception e){
135 throw new GateRuntimeException(
136 "Compile error while loading Jape transducer \"" + name + "\"!", e);
137 }
138
139 fsm = new FSM(this);
141 rules.clear();
143 rules = null;
144 }
146 private void addAnnotationsByOffset( SimpleSortedSet keys, Set annotations){
149 Iterator annIter = annotations.iterator();
150 while(annIter.hasNext()){
151 Annotation ann = (Annotation)annIter.next();
152 long offset = ann.getStartNode().getOffset().longValue();
154 if(offset == ann.getEndNode().getOffset().longValue())
155 continue;
156
169 keys.add(offset, ann);
171 }
172 }
174
175
179 public void transduce(Document doc, AnnotationSet inputAS,
180 AnnotationSet outputAS) throws JapeException,
181 ExecutionException {
182 interrupted = false;
183 fireProgressChanged(0);
184
185 SimpleSortedSet offsets = new SimpleSortedSet();
188 SimpleSortedSet annotationsByOffset = offsets;
189
190 if(input.isEmpty()) {
192 addAnnotationsByOffset(offsets, inputAS);
193 } else {
194 Iterator typesIter = input.iterator();
195 AnnotationSet ofOneType = null;
196 while(typesIter.hasNext()){
197 ofOneType = inputAS.get((String)typesIter.next());
198 if(ofOneType != null){
199 addAnnotationsByOffset(offsets, ofOneType);
200 }
201 }
202 }
203
204 if(annotationsByOffset.isEmpty()){
205 fireProcessFinished();
206 return;
207 }
208
209 annotationsByOffset.sort();
210 java.util.ArrayList activeFSMInstances = new java.util.ArrayList();
213
214 java.util.ArrayList acceptingFSMInstances = new ArrayList();
218 FSMInstance currentFSM;
219
220
221 Node startNode = ((Annotation)
223 ((ArrayList)annotationsByOffset.get(offsets.first())).get(0)).
224 getStartNode();
225
226 long lastNodeOff = doc.getContent().size().longValue();
228
229 long startNodeOff = startNode.getOffset().longValue();
232
233 long oldStartNodeOff = 0;
235
236 if (gate.Gate.isEnableJapeDebug()) {
238 if (null != phaseController) {
240 rulesTrace = new TraceContainer();
241 rulesTrace.putPhaseCut(this, inputAS);
242 }
243 }
244
246 while(startNodeOff != -1){
248 currentFSM = new FSMInstance(
252 fsm,
253 fsm.getInitialState(), startNode, startNode, new java.util.HashMap(), doc
258 );
259
260 activeFSMInstances.clear();
262 acceptingFSMInstances.clear();
263 activeFSMInstances.add(currentFSM);
264
265 whileloop2:
267 while(!activeFSMInstances.isEmpty()){
268 if(interrupted) throw new ExecutionInterruptedException(
269 "The execution of the \"" + getName() +
270 "\" Jape transducer has been abruptly interrupted!");
271
272 currentFSM = (FSMInstance)activeFSMInstances.remove(0);
274
275 if(currentFSM.getFSMPosition().isFinal()){
277 acceptingFSMInstances.add(currentFSM.clone());
279 if(ruleApplicationStyle == FIRST_STYLE) break whileloop2;
281 }
282
283 SimpleSortedSet offsetsTailSet = offsets.tailSet(currentFSM.
285 getAGPosition().getOffset().longValue());
286 ArrayList paths;
287 long theFirst = offsetsTailSet.first();
288 if(theFirst <0) continue;
289 paths = (ArrayList)annotationsByOffset.get(theFirst);
290 if(paths.isEmpty()) continue;
291 Iterator pathsIter = paths.iterator();
292 Annotation onePath;
293 State currentState = currentFSM.getFSMPosition();
294 Iterator transitionsIter;
295 while(pathsIter.hasNext()){
297 onePath = (Annotation)pathsIter.next();
298 transitionsIter = currentState.getTransitions().iterator();
299 Transition currentTransition;
300 Constraint[] currentConstraints;
301 transitionsWhile:
302 while(transitionsIter.hasNext()){
303 currentTransition = (Transition)transitionsIter.next();
304 currentConstraints =
306 currentTransition.getConstraints().getConstraints();
307 String annType;
308 int currentConstraintsindex = -1;
310 for(int i = 0; i<currentConstraints.length; i++){
312 annType = currentConstraints[i].getAnnotType();
313 if(!annType.equals(onePath.getType()))continue transitionsWhile;
315 currentConstraintsindex = i;
316 break;
317 }
318
319
320
321 if(onePath.getFeatures().
322 subsumes(ontology,
323 currentConstraints[currentConstraintsindex].
324 getAttributeSeq())){
325 FSMInstance newFSMI = (FSMInstance)currentFSM.clone();
329 newFSMI.setAGPosition(onePath.getEndNode());
330 newFSMI.setFSMPosition(currentTransition.getTarget());
331
332 if(gate.Gate.isEnableJapeDebug()) {
334 if (null != phaseController) {
335 currRuleTrace = rulesTrace.getStateContainer(currentFSM.
336 getFSMPosition());
337 if (currRuleTrace == null) {
338 currRuleTrace = new RuleTrace(newFSMI.getFSMPosition(), doc);
339 currRuleTrace.addAnnotation(onePath);
340 currRuleTrace.putPattern(onePath,
341 currentConstraints[currentConstraintsindex].
342 getAttributeSeq());
343 rulesTrace.add(currRuleTrace);
344 }
345 else {
346 currRuleTrace.addState(newFSMI.getFSMPosition());
347 currRuleTrace.addAnnotation(onePath);
348 currRuleTrace.putPattern(onePath,
349 currentConstraints[currentConstraintsindex].
350 getAttributeSeq());
351 }
352 }
353 }
354
356 java.util.Map binds = newFSMI.getBindings();
358 java.util.Iterator labelsIter =
359 currentTransition.getBindings().iterator();
360 String oneLabel;
361 AnnotationSet boundAnnots, newSet;
362 while(labelsIter.hasNext()){
363 oneLabel = (String)labelsIter.next();
364 boundAnnots = (AnnotationSet)binds.get(oneLabel);
365 if(boundAnnots != null)
366 newSet = new AnnotationSetImpl((AnnotationSet)boundAnnots);
367 else
368 newSet = new AnnotationSetImpl(doc);
369 newSet.add(onePath);
370 binds.put(oneLabel, newSet);
371
372 } activeFSMInstances.add(newFSMI);
374 } } } }
379 long lastAGPosition = -1;
381 if(acceptingFSMInstances.isEmpty()){
382 lastAGPosition = startNodeOff + 1;
384 } else if(ruleApplicationStyle == BRILL_STYLE) {
385 java.util.Iterator accFSMIter = acceptingFSMInstances.iterator();
387 FSMInstance currentAcceptor;
388 RightHandSide currentRHS;
389 lastAGPosition = startNode.getOffset().longValue();
390
391 while(accFSMIter.hasNext()){
392 currentAcceptor = (FSMInstance) accFSMIter.next();
393 currentRHS = currentAcceptor.getFSMPosition().getAction();
394
395 if (gate.Gate.isEnableJapeDebug()) {
398 if (null != phaseController) {
399 SPTLock lock = new SPTLock();
400 phaseController.TraceTransit(rulesTrace);
401 rulesTrace = new TraceContainer();
402 phaseController.RuleMatched(lock, this, currentRHS, doc,
403 currentAcceptor.getBindings(),
404 inputAS, outputAS);
405 }
406 }
407
409 currentRHS.transduce(doc, currentAcceptor.getBindings(),
410 inputAS, outputAS, ontology);
411
412 if (gate.Gate.isEnableJapeDebug()) {
415 if (null != phaseController) {
416 SPTLock lock = new SPTLock();
417 phaseController.RuleFinished(lock, this, currentRHS, doc,
418 currentAcceptor.getBindings(),
419 inputAS, outputAS);
420 }
421 }
422
424 long currentAGPosition = currentAcceptor.getAGPosition().getOffset().longValue();
425 if(currentAGPosition > lastAGPosition)
426 lastAGPosition = currentAGPosition;
427 }
428 } else if(ruleApplicationStyle == APPELT_STYLE ||
429 ruleApplicationStyle == FIRST_STYLE ||
430 ruleApplicationStyle == ONCE_STYLE) {
431
432 Collections.sort(acceptingFSMInstances, Collections.reverseOrder());
435 Iterator accFSMIter = acceptingFSMInstances.iterator();
436 FSMInstance currentAcceptor = (FSMInstance)accFSMIter.next();
437 if(isDebugMode()){
438 Iterator accIter = acceptingFSMInstances.iterator();
440 FSMInstance anAcceptor;
441 List conflicts = new ArrayList();
442 while(accIter.hasNext()){
443 anAcceptor = (FSMInstance)accIter.next();
444 if(anAcceptor.equals(currentAcceptor)){
445 conflicts.add(anAcceptor);
446 }else{
447 break;
448 }
449 }
450 if(conflicts.size() > 1){
451 Out.prln("\nConflicts found during matching:" +
452 "\n================================");
453 accIter = conflicts.iterator();
454 int i = 0;
455 while(accIter.hasNext()){
456 Out.prln(i++ + ") " + accIter.next().toString());
457 }
458 }
459 }
460 RightHandSide currentRHS = currentAcceptor.getFSMPosition().getAction();
461
462 if(gate.Gate.isEnableJapeDebug()) {
465 if (null != phaseController) {
466 SPTLock lock = new SPTLock();
467 rulesTrace.leaveLast(currentRHS);
468 phaseController.TraceTransit(rulesTrace);
469 rulesTrace = new TraceContainer();
470 phaseController.RuleMatched(lock, this, currentRHS, doc,
471 currentAcceptor.getBindings(),
472 inputAS, outputAS);
473 }
474 }
475
477 currentRHS.transduce(doc, currentAcceptor.getBindings(),
478 inputAS, outputAS, ontology);
479
480 if(gate.Gate.isEnableJapeDebug()) {
483 if (null != phaseController) {
484 SPTLock lock = new SPTLock();
485 phaseController.RuleFinished(lock, this, currentRHS, doc,
486 currentAcceptor.getBindings(),
487 inputAS, outputAS);
488 }
489 }
490
492 if(isMatchGroupMode()) {
494 String currentAcceptorString = null;
498 multiModeWhile: while(accFSMIter.hasNext()) {
499 FSMInstance rivalAcceptor =(FSMInstance) accFSMIter.next();
500 if(rivalAcceptor.compareTo(currentAcceptor)==0){
504 if(!rivalAcceptor.equals(currentAcceptor)){
507 if (isDebugMode()){
508 if (currentAcceptorString == null) {
509 currentAcceptorString = currentAcceptor.toString();
511 Out.prln("~Jape Grammar Transducer : "+
512 "\nConcurrent Patterns by length,priority and index (all transduced):");
513 Out.prln(currentAcceptorString);
514 Out.prln("bindings : "+currentAcceptor.getBindings());
515 Out.prln("Rivals Follow: ");
516 }
517 Out.prln(rivalAcceptor);
518 Out.prln("bindings : "+rivalAcceptor.getBindings());
519 } currentRHS = rivalAcceptor.getFSMPosition().getAction();
521
522 if(gate.Gate.isEnableJapeDebug()) {
525 if (null != phaseController) {
526 SPTLock lock = new SPTLock();
527 rulesTrace.leaveLast(currentRHS);
528 phaseController.TraceTransit(rulesTrace);
529 rulesTrace = new TraceContainer();
530 phaseController.RuleMatched(lock, this, currentRHS, doc,
531 rivalAcceptor.getBindings(),
532 inputAS, outputAS);
533 }
534 }
535
537 currentRHS.transduce(doc, rivalAcceptor.getBindings(),
538 inputAS, outputAS, ontology);
539
540 if(gate.Gate.isEnableJapeDebug()) {
543 if (null != phaseController) {
544 SPTLock lock = new SPTLock();
545 phaseController.RuleFinished(lock, this, currentRHS, doc,
546 rivalAcceptor.getBindings(),
547 inputAS, outputAS);
548 }
549 }
550 } }else{
553 break multiModeWhile;
556 }
557 } }
560 if(ruleApplicationStyle == ONCE_STYLE) return;
562
563 lastAGPosition = currentAcceptor.getAGPosition().getOffset().longValue();
565 }else throw new RuntimeException("Unknown rule application style!");
566
567
568 SimpleSortedSet OffsetsTailSet = offsets.tailSet(lastAGPosition);
570 long theFirst = OffsetsTailSet.first();
571 if( theFirst < 0){
572 startNodeOff = -1;
574 fireProcessFinished();
575 }else{
576 long nextKey = theFirst;
577 startNode = ((Annotation)
578 ((ArrayList)annotationsByOffset.get(nextKey)).get(0)). getStartNode();
580 startNodeOff = startNode.getOffset().longValue();
581
582 if(oldStartNodeOff == startNodeOff){
584 lastAGPosition = startNodeOff + 1;
586 OffsetsTailSet = offsets.tailSet(lastAGPosition);
587 theFirst = OffsetsTailSet.first();
588 if(theFirst < 0){
589 startNodeOff = -1;
591 fireProcessFinished();
592 }else{
593 nextKey = theFirst;
594 startNode = ((Annotation)
595 ((List)annotationsByOffset.get(theFirst)).get(0)).
596 getStartNode();
597 startNodeOff =startNode.getOffset().longValue();
598 }
599 } if(startNodeOff - oldStartNodeOff > 256){
602 if(isInterrupted()) throw new ExecutionInterruptedException(
603 "The execution of the \"" + getName() +
604 "\" Jape transducer has been abruptly interrupted!");
605
606 fireProgressChanged((int)(100 * startNodeOff / lastNodeOff));
607 oldStartNodeOff = startNodeOff;
608 }
609 }
610 } fireProcessFinished();
612
613 if(gate.Gate.isEnableJapeDebug()) {
615 if (null != phaseController) {
616 phaseController.TraceTransit(rulesTrace);
617 }
618 }
619
621 }
623
624
625 public void cleanUp() {
626 }
630
631 public String toString() {
632 return toString("");
633 }
635
636 public String toString(String pad) {
637 String newline = Strings.getNl();
638 String newPad = Strings.addPadding(pad, INDENT_PADDING);
639
640 StringBuffer buf =
641 new StringBuffer(pad + "SPT: name(" + name + "); ruleApplicationStyle(");
642
643 switch(ruleApplicationStyle) {
644 case APPELT_STYLE: buf.append("APPELT_STYLE); "); break;
645 case BRILL_STYLE: buf.append("BRILL_STYLE); "); break;
646 default: break;
647 }
648
649 buf.append("rules(" + newline);
650 Iterator rulesIterator = rules.iterator();
651 while(rulesIterator.hasNext())
652 buf.append(((Rule) rulesIterator.next()).toString(newPad) + " ");
653
654 buf.append(newline + pad + ")." + newline);
655
656 return buf.toString();
657 }
659 public PrioritisedRuleList getRules() {
661 return rules;
662 }
663
664
670 public void addInput(String ident) {
671 input.add(ident);
672 }
673 public synchronized void removeProgressListener(ProgressListener l) {
674 if (progressListeners != null && progressListeners.contains(l)) {
675 Vector v = (Vector) progressListeners.clone();
676 v.removeElement(l);
677 progressListeners = v;
678 }
679 }
680 public synchronized void addProgressListener(ProgressListener l) {
681 Vector v = progressListeners == null ? new Vector(2) : (Vector) progressListeners.clone();
682 if (!v.contains(l)) {
683 v.addElement(l);
684 progressListeners = v;
685 }
686 }
687
688
694 public java.util.Set input = new java.util.HashSet();
696 private transient Vector progressListeners;
699
700 protected void fireProgressChanged(int e) {
701 if (progressListeners != null) {
702 Vector listeners = progressListeners;
703 int count = listeners.size();
704 for (int i = 0; i < count; i++) {
705 ((ProgressListener) listeners.elementAt(i)).progressChanged(e);
706 }
707 }
708 }
709 protected void fireProcessFinished() {
710 if (progressListeners != null) {
711 Vector listeners = progressListeners;
712 int count = listeners.size();
713 for (int i = 0; i < count; i++) {
714 ((ProgressListener) listeners.elementAt(i)).processFinished();
715 }
716 }
717 }
718 public int getRuleApplicationStyle() {
719 return ruleApplicationStyle;
720 }
721
722
729
730
731 }
733