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