Revision: 15276
          http://gate.svn.sourceforge.net/gate/?rev=15276&view=rev
Author:   valyt
Date:     2012-01-31 11:08:09 +0000 (Tue, 31 Jan 2012)
Log Message:
-----------
Support for standard JAPE custom predicates.

Modified Paths:
--------------
    gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/Predicate.java
    gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBase.java
    gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBuilder.java

Added Paths:
-----------
    gate/trunk/plugins/JAPE_Plus/test/test-not-contains.jape
    gate/trunk/plugins/JAPE_Plus/test/test-not-within.jape

Modified: gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/Predicate.java
===================================================================
--- gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/Predicate.java      
2012-01-31 10:46:42 UTC (rev 15275)
+++ gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/Predicate.java      
2012-01-31 11:08:09 UTC (rev 15276)
@@ -16,6 +16,7 @@
 package gate.jape.plus;
 
 import gate.jape.constraint.AnnotationAccessor;
+import gate.jape.constraint.ConstraintPredicate;
 
 import java.util.regex.Pattern;
 
@@ -36,24 +37,29 @@
     REGEX_NOT_FIND,
     REGEX_NOT_MATCH,
     CONTAINS,
-    WITHIN
+    WITHIN,
+    CUSTOM
   }
 
   
   /**
    * The annotation feature this predicate refers to.
    */
-//  protected String featureName;
-  
   protected AnnotationAccessor annotationAccessor;
   
   /**
-   * The desired value for the feature. The only allowed types are 
-   * {@link String}, {@link Long}, {@link Double}, {@link Pattern} (for REGEX 
-   * predicates), or an int[] with annotationType, negated, pred1, pred2, ... 
+   * The desired value for the feature. The only allowed types are
+   * <ul>
+   * <li>{@link String}</li>
+   * <li>{@link Long}</li>
+   * <li>{@link Double}</li>
+   * <li>{@link Pattern} (for REGEX predicates)</li> 
+   * <li>int[] with annotationType, negated, pred1, pred2, ... 
    * (i.e. constraints in the same format as 
    * {@link SPTBase.Transition#constraints}) used by CONTAINS and WITHIN 
-   * predicates to validate potential matches!
+   * predicates to validate potential matches</li>
+   * <li>a {@link ConstraintPredicate} value, for CUSTOM predicates.</li>
+   * </ul>
    */
   protected Object featureValue;
   

Modified: gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBase.java
===================================================================
--- gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBase.java        
2012-01-31 10:46:42 UTC (rev 15275)
+++ gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBase.java        
2012-01-31 11:08:09 UTC (rev 15276)
@@ -49,6 +49,7 @@
 import cern.colt.function.IntComparator;
 import cern.colt.list.IntArrayList;
 import gate.jape.ControllerEventBlocksAction;
+import gate.jape.constraint.ConstraintPredicate;
 
 /**
  * An optimised implementation for a JAPE single phase transducer.
@@ -65,7 +66,7 @@
    * @return <code>true</code> if the process should be stopped (e.g. an 
    * accepting instance has been found, and the matching mode is FIRST or 
ONCE). 
    */
-  protected abstract boolean advanceInstance(FSMInstance instance);
+  protected abstract boolean advanceInstance(FSMInstance instance) throws 
JapeException;
   
   /**
    * Sets the action context to be used during execution of RHS actions.
@@ -737,8 +738,11 @@
    *          {@link #predicatesByType} array corresponding to the type of the
    *          annotation.
    * @return <code>true</code> iff the annotation is accepted by the predicate.
+   * @throws JapeException if a custom predicate generates it while performing
+   * the test.
    */
-  protected boolean checkPredicate(int annotationId, int predicateId) {
+  protected boolean checkPredicate(int annotationId, int predicateId) 
+      throws JapeException {
     if(!QuickBitVector.get(annotationPredicateComputed[annotationId],
             predicateId)) {
       predicateMisses++;
@@ -791,7 +795,7 @@
             predicateId);
   }
 
-  protected boolean calculatePredicateValue(int annotationId, int predicateId) 
{
+  protected boolean calculatePredicateValue(int annotationId, int predicateId) 
throws JapeException {
     Predicate predicate =
             predicatesByType[annotationType[annotationId]][predicateId];
     
@@ -977,74 +981,80 @@
               (String)actualValue).matches();
         }
         break;
-      case CONTAINS:{
-        int[] constraints = (int[])predicate.featureValue;
-        // find all annotations contained in this annotation
-        // annotations are sorted by start offset
-        int currAnnIdx = annotationId;
-        long startOffset = annotation[annotationId].getStartNode().getOffset();
-        long endOffset = annotation[annotationId].getEndNode().getOffset();
-        // move left until we find the first annotation starting here
-        while(currAnnIdx > 0 && 
-            annotation[currAnnIdx -1].getStartNode().getOffset() == 
startOffset) {
-          currAnnIdx--;
-        }
-        while(currAnnIdx < annotation.length &&
-              annotation[currAnnIdx].getStartNode().getOffset() <= endOffset) {
-          if(annotationType[currAnnIdx] == constraints[0] &&
-             annotation[currAnnIdx].getEndNode().getOffset() <= endOffset) {
-            // annotation is of correct type and contained
-            // now check the constraint predicates
-            boolean predicatesHappy = true;
-            for(int predIdx = 2;
-                predIdx < constraints.length && predicatesHappy; 
-                predIdx++) {
-              predicatesHappy &= (checkPredicate(currAnnIdx, 
constraints[predIdx]));
+      case CONTAINS:
+        {
+          int[] constraints = (int[])predicate.featureValue;
+          // find all annotations contained in this annotation
+          // annotations are sorted by start offset
+          int currAnnIdx = annotationId;
+          long startOffset = 
annotation[annotationId].getStartNode().getOffset();
+          long endOffset = annotation[annotationId].getEndNode().getOffset();
+          // move left until we find the first annotation starting here
+          while(currAnnIdx > 0 && 
+              annotation[currAnnIdx -1].getStartNode().getOffset() == 
startOffset) {
+            currAnnIdx--;
+          }
+          while(currAnnIdx < annotation.length &&
+                annotation[currAnnIdx].getStartNode().getOffset() <= 
endOffset) {
+            if(annotationType[currAnnIdx] == constraints[0] &&
+               annotation[currAnnIdx].getEndNode().getOffset() <= endOffset) {
+              // annotation is of correct type and contained
+              // now check the constraint predicates
+              boolean predicatesHappy = true;
+              for(int predIdx = 2;
+                  predIdx < constraints.length && predicatesHappy; 
+                  predIdx++) {
+                predicatesHappy &= (checkPredicate(currAnnIdx, 
constraints[predIdx]));
+              }
+              if((constraints[1] >= 0 && predicatesHappy) ||
+                 // negated constraint 
+                 (constraints[1] < 0 && !predicatesHappy)) {
+                result = true;
+                break predtype;
+              }
             }
-            if((constraints[1] >= 0 && predicatesHappy) ||
-               // negated constraint 
-               (constraints[1] < 0 && !predicatesHappy)) {
-              result = true;
-              break predtype;
-            }
+            // try the next ann
+            currAnnIdx++;
           }
-          // try the next ann
-          currAnnIdx++;
         }
-      }
-      break;
-      case WITHIN: {
-        int[] constraints = (int[])predicate.featureValue;
-        // find all annotations containing this annotation
-        // annotations are sorted by start offset
-        int currAnnIdx = 0;
-        int maxCurrAnn = annotationNextOffset[annotationId];
-        if(maxCurrAnn >= annotation.length) maxCurrAnn = annotation.length;
-        long endOffset = annotation[annotationId].getEndNode().getOffset();
-        // move left until we find the first annotation starting here
-        while(currAnnIdx < maxCurrAnn) {
-          if(annotationType[currAnnIdx] == constraints[0] &&
-             annotation[currAnnIdx].getEndNode().getOffset() >= endOffset) {
-            // annotation is of correct type and contains the current one
-            // now check the constraint predicates
-            boolean predicatesHappy = true;
-            for(int predIdx = 2;
-                predIdx < constraints.length && predicatesHappy; 
-                predIdx++) {
-              predicatesHappy &= (checkPredicate(currAnnIdx, 
constraints[predIdx]));
+        break;
+      case WITHIN: 
+        {
+          int[] constraints = (int[])predicate.featureValue;
+          // find all annotations containing this annotation
+          // annotations are sorted by start offset
+          int currAnnIdx = 0;
+          int maxCurrAnn = annotationNextOffset[annotationId];
+          if(maxCurrAnn >= annotation.length) maxCurrAnn = annotation.length;
+          long endOffset = annotation[annotationId].getEndNode().getOffset();
+          // move left until we find the first annotation starting here
+          while(currAnnIdx < maxCurrAnn) {
+            if(annotationType[currAnnIdx] == constraints[0] &&
+               annotation[currAnnIdx].getEndNode().getOffset() >= endOffset) {
+              // annotation is of correct type and contains the current one
+              // now check the constraint predicates
+              boolean predicatesHappy = true;
+              for(int predIdx = 2;
+                  predIdx < constraints.length && predicatesHappy; 
+                  predIdx++) {
+                predicatesHappy &= (checkPredicate(currAnnIdx, 
constraints[predIdx]));
+              }
+              if((constraints[1] >= 0 && predicatesHappy) ||
+                 // negated constraint 
+                 (constraints[1] < 0 && !predicatesHappy)) {
+                result = true;
+                break predtype;
+              }
             }
-            if((constraints[1] >= 0 && predicatesHappy) ||
-               // negated constraint 
-               (constraints[1] < 0 && !predicatesHappy)) {
-              result = true;
-              break predtype;
-            }
+            // try the next ann
+            currAnnIdx++;
           }
-          // try the next ann
-          currAnnIdx++;
         }
-      }
-      break;
+        break;
+      case CUSTOM:
+        ConstraintPredicate actualConstraint = 
(ConstraintPredicate)predicate.featureValue;
+        result = actualConstraint.matches(annotation[annotationId], inputAS);
+        break;
       default:
         throw new IllegalArgumentException("Predicate type " + predicate.type
                 + " not implemented");
@@ -1082,7 +1092,11 @@
         // advance the top instance, and queue all resulting instances.
         // get the first instance
         FSMInstance fsmInstance = activeInstances.removeFirst();
-        if(advanceInstance(fsmInstance)) break instances;
+        try {
+          if(advanceInstance(fsmInstance)) break instances;
+        } catch(JapeException e) {
+          throw new ExecutionException(e);
+        }
       }// while activeInstances not empty
       // at this point, there are no more active instances (or we exited due to
       // matching mode being First or Once).

Modified: gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBuilder.java
===================================================================
--- gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBuilder.java     
2012-01-31 10:46:42 UTC (rev 15275)
+++ gate/trunk/plugins/JAPE_Plus/src/gate/jape/plus/SPTBuilder.java     
2012-01-31 11:08:09 UTC (rev 15276)
@@ -194,6 +194,7 @@
                                   StringBuilder out) {
     out.append("package ").append(GENERATED_CLASS_PACKAGE).append(";\n");
     out.append("import gate.jape.Rule;\n");
+    out.append("import gate.jape.JapeException;\n");
     out.append("import gate.jape.plus.Predicate;\n");
     out.append("import gate.jape.plus.SPTBase;\n");
     out.append("import cern.colt.list.IntArrayList;\n");
@@ -265,7 +266,7 @@
   
   protected void writeAdvanceInstanceMethod(int tabs, StringBuilder out) {
     out.append(TABS[tabs]).append("@Override\n");
-    out.append(TABS[tabs]).append("protected final boolean 
advanceInstance(FSMInstance instance) {\n");
+    out.append(TABS[tabs]).append("protected final boolean 
advanceInstance(FSMInstance instance) throws JapeException {\n");
     tabs++;
     out.append(TABS[tabs]).append("switch(instance.state) {\n");
     tabs++;
@@ -285,7 +286,7 @@
   
   protected void writeStateMethod(int stateId, int tabs, StringBuilder out) {
     out.append(TABS[tabs]).append("private final boolean state").append(
-      stateId).append('(').append("FSMInstance instance").append("){\n");
+      stateId).append('(').append("FSMInstance instance").append(") throws 
JapeException {\n");
     tabs++;
     State state = newStates.get(stateId);
     // if final state
@@ -599,32 +600,32 @@
     String operator = oldPredicate.getOperator();
     if(operator == ConstraintPredicate.EQUAL){
       newPredicate.type = PredicateType.EQ;
-    }else if(operator == ConstraintPredicate.GREATER){
+    } else if(operator == ConstraintPredicate.GREATER){
       newPredicate.type = PredicateType.GT;
-    }else if(operator == ConstraintPredicate.GREATER_OR_EQUAL){
+    } else if(operator == ConstraintPredicate.GREATER_OR_EQUAL){
       newPredicate.type = PredicateType.GE;
-    }else if(operator == ConstraintPredicate.LESSER){
+    } else if(operator == ConstraintPredicate.LESSER){
       newPredicate.type = PredicateType.LT;
-    }else if(operator == ConstraintPredicate.LESSER_OR_EQUAL){
+    } else if(operator == ConstraintPredicate.LESSER_OR_EQUAL){
       newPredicate.type = PredicateType.LE;
-    }else if(operator == ConstraintPredicate.NOT_EQUAL){
+    } else if(operator == ConstraintPredicate.NOT_EQUAL){
       newPredicate.type = PredicateType.NOT_EQ;
-    }else if(operator == ConstraintPredicate.NOT_REGEXP_FIND){
+    } else if(operator == ConstraintPredicate.NOT_REGEXP_FIND){
       newPredicate.type = PredicateType.REGEX_NOT_FIND;
-    }else if(operator == ConstraintPredicate.NOT_REGEXP_MATCH){
+    } else if(operator == ConstraintPredicate.NOT_REGEXP_MATCH){
       newPredicate.type = PredicateType.REGEX_NOT_MATCH;
-    }else if(operator == ConstraintPredicate.REGEXP_FIND){
+    } else if(operator == ConstraintPredicate.REGEXP_FIND){
       newPredicate.type = PredicateType.REGEX_FIND;
-    }else if(operator == ConstraintPredicate.REGEXP_MATCH){
+    } else if(operator == ConstraintPredicate.REGEXP_MATCH){
       newPredicate.type = PredicateType.REGEX_MATCH;
-    }else if(operator == ContainsPredicate.OPERATOR){
+    } else if(operator == ContainsPredicate.OPERATOR){
       newPredicate.type = PredicateType.CONTAINS;
-    }else if(operator == WithinPredicate.OPERATOR){
+    } else if(operator == WithinPredicate.OPERATOR){
       newPredicate.type = PredicateType.WITHIN;
-    }else{
-      throw new ResourceInstantiationException(
-              "Constraint predicates with operator \"" + operator +
-              "\" are not supported in JAPE-Plus!");
+    } else {
+      // make it into a custom predicate
+      newPredicate.type = PredicateType.CUSTOM;
+      newPredicate.featureValue = oldPredicate;
     }
     if(newPredicate.type == PredicateType.CONTAINS) {
       String containedAnnType = null;
@@ -690,7 +691,10 @@
         newPredValue[predIdx++] = predId;
       }
       newPredicate.featureValue = newPredValue;
+    } else if(newPredicate.type == PredicateType.CUSTOM) {
+      // do nothing
     } else {
+      // for all other types of predicates, copy the value
       newPredicate.featureValue = oldPredicate.getValue();
     }
     //now see if this is a new predicate or not

Added: gate/trunk/plugins/JAPE_Plus/test/test-not-contains.jape
===================================================================
--- gate/trunk/plugins/JAPE_Plus/test/test-not-contains.jape                    
        (rev 0)
+++ gate/trunk/plugins/JAPE_Plus/test/test-not-contains.jape    2012-01-31 
11:08:09 UTC (rev 15276)
@@ -0,0 +1,19 @@
+Phase: Contains
+Input: A B C
+Options: control = appelt
+
+
+Rule: A
+({A notContains {C}}):bind
+-->
+:bind.Out = {},
+:bind {
+  System.out.print("[");
+  boolean first = true;
+  for(Annotation ann: bindAnnots){
+    if(first) first = false; else System.out.print(", ");
+    System.out.print(ann.getId());
+  }
+  System.out.println("]");
+}
+

Added: gate/trunk/plugins/JAPE_Plus/test/test-not-within.jape
===================================================================
--- gate/trunk/plugins/JAPE_Plus/test/test-not-within.jape                      
        (rev 0)
+++ gate/trunk/plugins/JAPE_Plus/test/test-not-within.jape      2012-01-31 
11:08:09 UTC (rev 15276)
@@ -0,0 +1,19 @@
+Phase: Contains
+Input: A B C
+Options: control = appelt
+
+
+Rule: A
+({B notWithin {C}}):bind
+-->
+:bind.Out = {},
+:bind {
+  System.out.print("[");
+  boolean first = true;
+  for(Annotation ann: bindAnnots){
+    if(first) first = false; else System.out.print(", ");
+    System.out.print(ann.getId());
+  }
+  System.out.println("]");
+}
+

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
GATE-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gate-cvs

Reply via email to