Author: pkluegl Date: Fri Mar 22 16:45:30 2013 New Revision: 1459894 URL: http://svn.apache.org/r1459894 Log: UIMA-2757 - added wildcard rule element - added test - documentation and more tests still missing
Added: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/WildCardRuleElement.java uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/WildCardTest.java uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.tm uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.txt Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerLexer.g uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerParser.g uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerScriptFactory.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerStream.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/ComposedRuleElement.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/RuleElementCaretaker.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerLiteralMatcher.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerRuleElement.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerTypeMatcher.java uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/verbalize/ScriptVerbalizer.java uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/AllTests.java uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerLexer.g uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerParser.g uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/TextMarkerKeywords.java uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/parser/DLTKTextMarkerErrorReporter.java uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/AbstractFactory.java uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/ScriptFactory.java Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerLexer.g URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerLexer.g?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerLexer.g (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerLexer.g Fri Mar 22 16:45:30 2013 @@ -511,6 +511,9 @@ LESSEQUAL : '<=' ; GREATEREQUAL : '>=' ; + +WILDCARD : '#' ; + WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} ; Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerParser.g URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerParser.g?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerParser.g (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/antlr3/org/apache/uima/textmarker/parser/TextMarkerParser.g Fri Mar 22 16:45:30 2013 @@ -75,6 +75,7 @@ import org.apache.uima.textmarker.expres import org.apache.uima.textmarker.expression.string.StringFunctionFactory; import org.apache.uima.textmarker.expression.type.TypeExpression; import org.apache.uima.textmarker.extensions.TextMarkerExternalFactory; +import org.apache.uima.textmarker.rule.AbstractRuleElement; import org.apache.uima.textmarker.rule.ComposedRuleElement; import org.apache.uima.textmarker.rule.RegExpRule; import org.apache.uima.textmarker.rule.RuleElement; @@ -567,8 +568,26 @@ ruleElement[RuleElementContainer contain | re2 = ruleElementLiteral[container] {re = re2;} | (ruleElementComposed[null])=>re3 = ruleElementComposed[container] {re = re3;} | (ruleElementDisjunctive[null])=> re4 = ruleElementDisjunctive[container] {re = re4;} + | (ruleElementWildCard[null])=> re5 = ruleElementWildCard[container] {re = re5;} ; +ruleElementWildCard [RuleElementContainer container] returns [AbstractRuleElement re = null] + : + + w = WILDCARD + {re = factory.createWildCardRuleElement(null, null, container, $blockDeclaration::env);} + (LCURLY c = conditions? (THEN a = actions)? RCURLY)? + { + if(c!= null) { + re.setConditions(c); + } + if(a != null) { + re.setActions(a); + } + } + ; + + ruleElementDisjunctive [RuleElementContainer container] returns [TextMarkerRuleElement re = null] @init{ List<TextMarkerExpression> exprs = new ArrayList<TextMarkerExpression>(); Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerScriptFactory.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerScriptFactory.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerScriptFactory.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerScriptFactory.java Fri Mar 22 16:45:30 2013 @@ -31,6 +31,7 @@ import org.apache.uima.textmarker.expres import org.apache.uima.textmarker.expression.string.StringExpression; import org.apache.uima.textmarker.expression.type.SimpleTypeExpression; import org.apache.uima.textmarker.expression.type.TypeExpression; +import org.apache.uima.textmarker.rule.AbstractRuleElement; import org.apache.uima.textmarker.rule.ComposedRuleElement; import org.apache.uima.textmarker.rule.RegExpRule; import org.apache.uima.textmarker.rule.RuleElement; @@ -41,6 +42,7 @@ import org.apache.uima.textmarker.rule.T import org.apache.uima.textmarker.rule.TextMarkerRule; import org.apache.uima.textmarker.rule.TextMarkerRuleElement; import org.apache.uima.textmarker.rule.TextMarkerTypeMatcher; +import org.apache.uima.textmarker.rule.WildCardRuleElement; import org.apache.uima.textmarker.rule.quantifier.MinMaxGreedy; import org.apache.uima.textmarker.rule.quantifier.MinMaxReluctant; import org.apache.uima.textmarker.rule.quantifier.PlusGreedy; @@ -119,6 +121,13 @@ public class TextMarkerScriptFactory { return new TextMarkerRuleElement(matcher, quantifier, conditions, actions, container, parent); } + public AbstractRuleElement createWildCardRuleElement(List<AbstractTextMarkerCondition> conditions, + List<AbstractTextMarkerAction> actions, RuleElementContainer container, + TextMarkerBlock parent) { + return new WildCardRuleElement(conditions, actions, container, parent); + } + + public TextMarkerRuleElement createRuleElement(List<TextMarkerExpression> exprs, RuleElementQuantifier quantifier, List<AbstractTextMarkerCondition> conditions, List<AbstractTextMarkerAction> actions, RuleElementContainer container, @@ -131,7 +140,6 @@ public class TextMarkerScriptFactory { RuleElementQuantifier quantifier, List<AbstractTextMarkerCondition> conditions, List<AbstractTextMarkerAction> actions, RuleElementContainer container, TextMarkerBlock parent) { - TextMarkerLiteralMatcher matcher = new TextMarkerLiteralMatcher(stringExpression); return new TextMarkerRuleElement(matcher, quantifier, conditions, actions, container, parent); } @@ -192,4 +200,6 @@ public class TextMarkerScriptFactory { return new RegExpRule(null, null, idCounter++, env); } + + } Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerStream.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerStream.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerStream.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/TextMarkerStream.java Fri Mar 22 16:45:30 2013 @@ -250,7 +250,7 @@ public class TextMarkerStream extends FS // TextMarkerBasic floor = floorEntry.getValue(); // TextMarkerBasic ceiling = ceilingEntry.getValue(); TextMarkerBasic floor = getFloor(endAnchors, anchor); - if(floor == null) { + if (floor == null) { floor = getFloor(beginAnchors, anchor); } TextMarkerBasic ceiling = getCeiling(endAnchors, anchor); @@ -526,14 +526,18 @@ public class TextMarkerStream extends FS if (before) { TextMarkerBasic pointer = beginAnchors.get(annotation.getBegin()); moveTo(pointer); - moveToPrevious(); + if(isVisible(pointer)) { + moveToPrevious(); + } if (isValid()) { return (TextMarkerBasic) get(); } } else { TextMarkerBasic pointer = endAnchors.get(annotation.getEnd()); moveTo(pointer); - moveToNext(); + if(isVisible(pointer)) { + moveToNext(); + } if (isValid()) { return (TextMarkerBasic) get(); } @@ -712,4 +716,22 @@ public class TextMarkerStream extends FS this.simpleGreedyForComposed = simpleGreedyForComposed; } + public boolean isVisible(AnnotationFS annotationFS) { + AnnotationFS windowAnnotation = filter.getWindowAnnotation(); + if (windowAnnotation != null && (annotationFS.getBegin() < windowAnnotation.getBegin() + || annotationFS.getEnd() > windowAnnotation.getEnd())) { + return false; + } + FSMatchConstraint defaultConstraint = filter.getDefaultConstraint(); + return defaultConstraint.match(annotationFS); + } + + public TextMarkerBasic getAnchor(boolean direction, int pointer) { + if(direction) { + return getBeginAnchor(pointer); + } else { + return getEndAnchor(pointer); + } + } + } Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/ComposedRuleElement.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/ComposedRuleElement.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/ComposedRuleElement.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/ComposedRuleElement.java Fri Mar 22 16:45:30 2013 @@ -129,13 +129,13 @@ public class ComposedRuleElement extends InferenceCrowd crowd) { RuleElementContainer container = getContainer(); doMatch(containerMatch, stream, crowd); - if (this.equals(entryPoint)) { + if (this.equals(entryPoint) && ruleApply == null) { return; } if (container == null) { fallback(after, failed, annotation, ruleMatch, ruleApply, containerMatch, sideStepOrigin, entryPoint, stream, crowd); - } else if (entryPoint == null) { + } else { ComposedRuleElementMatch parentContainerMatch = containerMatch.getContainerMatch(); RuleElement nextElement = container.getNextElement(after, this); List<RuleElementMatch> match = getMatch(ruleMatch, parentContainerMatch); Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/RuleElementCaretaker.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/RuleElementCaretaker.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/RuleElementCaretaker.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/RuleElementCaretaker.java Fri Mar 22 16:45:30 2013 @@ -57,7 +57,7 @@ public class RuleElementCaretaker implem public RuleElement getAnchoringRuleElement(TextMarkerStream stream) { List<RuleElement> ruleElements = container.getRuleElements(); - if (ruleElements.size() == 1) { + if (ruleElements.size() == 1 || containsLiteralMatcher(ruleElements)) { return ruleElements.get(0); } @@ -83,6 +83,18 @@ public class RuleElementCaretaker implem } + private boolean containsLiteralMatcher(List<RuleElement> ruleElements) { + for (RuleElement each : ruleElements) { + if(each instanceof TextMarkerRuleElement) { + TextMarkerRuleElement re = (TextMarkerRuleElement) each; + if(re.getMatcher() instanceof TextMarkerLiteralMatcher) { + return true; + } + } + } + return false; + } + public RuleElement getFirstElement() { List<RuleElement> ruleElements = container.getRuleElements(); return ruleElements.get(0); Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerLiteralMatcher.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerLiteralMatcher.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerLiteralMatcher.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerLiteralMatcher.java Fri Mar 22 16:45:30 2013 @@ -64,7 +64,7 @@ public class TextMarkerLiteralMatcher im return "\"" + expression.toString() + "\""; } - public TextMarkerExpression getExpression() { + public StringExpression getExpression() { return expression; } Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerRuleElement.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerRuleElement.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerRuleElement.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerRuleElement.java Fri Mar 22 16:45:30 2013 @@ -207,7 +207,7 @@ public class TextMarkerRuleElement exten doMatch(eachAnchor, extendedMatch, extendedContainerMatch, false, stream, crowd); - if (this.equals(entryPoint)) { + if (this.equals(entryPoint) && ruleApply == null) { return; } if (extendedMatch.matched()) { Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerTypeMatcher.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerTypeMatcher.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerTypeMatcher.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/TextMarkerTypeMatcher.java Fri Mar 22 16:45:30 2013 @@ -92,7 +92,9 @@ public class TextMarkerTypeMatcher imple return Collections.emptyList(); } stream.moveTo(lastBasic); - stream.moveToNext(); + if(stream.isVisible(annotation)) { + stream.moveToNext(); + } if (stream.isValid()) { TextMarkerBasic nextBasic = (TextMarkerBasic) stream.get(); List<Type> reTypes = getTypes(parent, stream); Added: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/WildCardRuleElement.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/WildCardRuleElement.java?rev=1459894&view=auto ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/WildCardRuleElement.java (added) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/rule/WildCardRuleElement.java Fri Mar 22 16:45:30 2013 @@ -0,0 +1,465 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.uima.textmarker.rule; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.apache.uima.cas.CAS; +import org.apache.uima.cas.ConstraintFactory; +import org.apache.uima.cas.FSIterator; +import org.apache.uima.cas.FSTypeConstraint; +import org.apache.uima.cas.Type; +import org.apache.uima.cas.text.AnnotationFS; +import org.apache.uima.textmarker.TextMarkerBlock; +import org.apache.uima.textmarker.TextMarkerStream; +import org.apache.uima.textmarker.action.AbstractTextMarkerAction; +import org.apache.uima.textmarker.condition.AbstractTextMarkerCondition; +import org.apache.uima.textmarker.expression.string.StringExpression; +import org.apache.uima.textmarker.type.TextMarkerBasic; +import org.apache.uima.textmarker.visitor.InferenceCrowd; + +public class WildCardRuleElement extends AbstractRuleElement { + + public WildCardRuleElement(List<AbstractTextMarkerCondition> conditions, + List<AbstractTextMarkerAction> actions, RuleElementContainer container, + TextMarkerBlock parent) { + super(null, conditions, actions, container, parent); + } + + public void startMatch(RuleMatch ruleMatch, RuleApply ruleApply, + ComposedRuleElementMatch containerMatch, RuleElement entryPoint, TextMarkerStream stream, + InferenceCrowd crowd) { + continueMatch(true, null, ruleMatch, ruleApply, containerMatch, null, entryPoint, stream, crowd); + } + + public void continueMatch(boolean after, AnnotationFS annotation, RuleMatch ruleMatch, + RuleApply ruleApply, ComposedRuleElementMatch containerMatch, + TextMarkerRuleElement sideStepOrigin, RuleElement entryPoint, TextMarkerStream stream, + InferenceCrowd crowd) { + RuleElement nextElement = getContainer().getNextElement(after, this); + + tryWithNextRuleElement(nextElement, after, annotation, ruleMatch, ruleApply, containerMatch, + sideStepOrigin, entryPoint, stream, crowd); + + } + + private void tryWithNextRuleElement(RuleElement nextElement, boolean after, + AnnotationFS annotation, RuleMatch ruleMatch, RuleApply ruleApply, + ComposedRuleElementMatch containerMatch, TextMarkerRuleElement sideStepOrigin, + RuleElement entryPoint, TextMarkerStream stream, InferenceCrowd crowd) { + // what is the next stuff that should match? + if (nextElement == null) { + AnnotationFS afs = getCoveredByWildCard(after, annotation, null, stream); + doMatch(afs, ruleMatch, containerMatch, annotation == null, stream, crowd); + ComposedRuleElement composed = (ComposedRuleElement) getContainer(); + composed.fallbackContinue(after, ruleMatch.matched(), afs, ruleMatch, ruleApply, + containerMatch, sideStepOrigin, entryPoint, stream, crowd); + } else if (nextElement instanceof TextMarkerRuleElement) { + TextMarkerRuleElement re = (TextMarkerRuleElement) nextElement; + TextMarkerMatcher matcher = re.getMatcher(); + if (matcher instanceof TextMarkerTypeMatcher) { + tryWithNextType(after, annotation, nextElement, null, ruleMatch, ruleApply, containerMatch, + sideStepOrigin, stream, crowd); + } else if (matcher instanceof TextMarkerLiteralMatcher) { + tryWithNextLiteral(after, annotation, re, ruleMatch, ruleApply, containerMatch, + sideStepOrigin, stream, crowd); + } else if (matcher instanceof TextMarkerDisjunctiveMatcher) { + tryWithNextType(after, annotation, re, null, ruleMatch, ruleApply, containerMatch, + sideStepOrigin, stream, crowd); + } + + } else if (nextElement instanceof ComposedRuleElement) { + + ComposedRuleElement cre = ((ComposedRuleElement) nextElement); + tryWithNextComposed(after, annotation, cre, ruleMatch, ruleApply, containerMatch, + sideStepOrigin, stream, crowd); + RuleElement nextInnerRuleElement = null; + if (after) { + nextInnerRuleElement = cre.getFirstElement(); + } else { + nextInnerRuleElement = cre.getLastElement(); + } + // TODO won't work ...!!! + ComposedRuleElementMatch composedMatch = new ComposedRuleElementMatch(cre, containerMatch); + if (containerMatch == null) { + ruleMatch.setRootMatch(composedMatch); + } else { + containerMatch.addInnerMatch(this, composedMatch, false); + } + tryWithNextRuleElement(nextInnerRuleElement, after, annotation, ruleMatch, ruleApply, + composedMatch, sideStepOrigin, entryPoint, stream, crowd); + } else if (nextElement instanceof WildCardRuleElement) { + // another wildcard? seriously? then just assume its an "Annotation" type + CAS cas = stream.getCas(); + tryWithNextType(after, annotation, nextElement, cas.getAnnotationType(), ruleMatch, + ruleApply, containerMatch, sideStepOrigin, stream, crowd); + } + } + + private void tryWithNextComposed(boolean after, AnnotationFS annotation, ComposedRuleElement cre, + RuleMatch ruleMatch, RuleApply ruleApply, ComposedRuleElementMatch containerMatch, + TextMarkerRuleElement sideStepOrigin, TextMarkerStream stream, InferenceCrowd crowd) { + AnnotationFS nextOne = annotation; + boolean doneHere = false; + while (!doneHere + && (nextOne = getNextPositionForComposed(cre, after, nextOne, stream)) != null) { + TextMarkerBasic endAnchor = stream.getEndAnchor(nextOne.getBegin()); + ComposedRuleElementMatch extendedContainerMatch = containerMatch.copy(); + RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch); + AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, nextOne, stream); + + doMatch(coveredByWildCard, extendedMatch, extendedContainerMatch, annotation == null, stream, + crowd); + if (extendedMatch.matched()) { + cre.continueMatch(after, endAnchor, extendedMatch, ruleApply, + extendedContainerMatch, sideStepOrigin, cre, stream, crowd); + List<RuleElementMatch> nextList = extendedContainerMatch.getInnerMatches().get(cre); + boolean matched = hasMatched(nextList); + if (!matched) { + nextOne = stream.getAnchor(after, getNextPointer(!after, nextOne)); + } else { + doneHere = true; + } + } else { + // conditions of wildcard element did not match, try the next possible anchor for the + // next rule element + nextOne = annotation; + } + } + if (!doneHere) { + cre.continueMatch(after, annotation, ruleMatch, ruleApply, containerMatch, sideStepOrigin, + null, stream, crowd); + } + } + + private boolean hasMatched(List<RuleElementMatch> nextList) { + if(nextList == null || nextList.isEmpty()) { + return false; + } + boolean result = true; + for (RuleElementMatch each : nextList) { + result &= each.matched(); + } + return result; + } + + private AnnotationFS getNextPositionForComposed(ComposedRuleElement cre, boolean after, + AnnotationFS annotation, TextMarkerStream stream) { + RuleElement element = getNextAtomicRuleElement(cre, after); + AnnotationFS result = null; + if (element instanceof WildCardRuleElement) { + if (after) { + return stream.getAnchor(after, annotation.getEnd()); + } else { + return stream.getAnchor(after, annotation.getBegin()); + } + } else { + TextMarkerRuleElement re = (TextMarkerRuleElement) element; + TextMarkerMatcher matcher = re.getMatcher(); + if (matcher instanceof TextMarkerTypeMatcher) { + FSIterator<AnnotationFS> iterator = getIterator(after, annotation, re, null, stream); +// moveOn(after, iterator); + if (iterator.isValid()) { + result = iterator.get(); + } + } else if (matcher instanceof TextMarkerLiteralMatcher) { + TextMarkerLiteralMatcher lm = (TextMarkerLiteralMatcher) matcher; + StringExpression expression = lm.getExpression(); + String stringValue = expression.getStringValue(parent); + AnnotationFS documentAnnotation = stream.getDocumentAnnotation(); + int delta = documentAnnotation.getBegin(); + String document = documentAnnotation.getCoveredText(); + int pointer = annotation.getEnd() - delta; + int indexOf = document.indexOf(stringValue, pointer); + if (indexOf < 0) { + return null; + } else { + return stream.getAnchor(after, indexOf); + } + } + } + + return result; + } + + private RuleElement getNextAtomicRuleElement(ComposedRuleElement cre, boolean after) { + if (after) { + RuleElement firstElement = cre.getFirstElement(); + if (firstElement instanceof ComposedRuleElement) { + return getNextAtomicRuleElement((ComposedRuleElement) firstElement, after); + } else { + return firstElement; + } + } else { + RuleElement lastElement = cre.getLastElement(); + if (lastElement instanceof ComposedRuleElement) { + return getNextAtomicRuleElement((ComposedRuleElement) lastElement, after); + } else { + return lastElement; + } + } + } + + private void tryWithNextType(boolean after, AnnotationFS annotation, RuleElement nextElement, + Type defaultType, RuleMatch ruleMatch, RuleApply ruleApply, + ComposedRuleElementMatch containerMatch, TextMarkerRuleElement sideStepOrigin, + TextMarkerStream stream, InferenceCrowd crowd) { + FSIterator<AnnotationFS> iterator = getIterator(after, annotation, nextElement, defaultType, + stream); + boolean doneHere = false; + while (!doneHere && iterator.isValid() && stream.isVisible(iterator.get())) { + AnnotationFS nextOne = iterator.get(); + TextMarkerBasic endAnchor = stream.getEndAnchor(nextOne.getBegin()); + ComposedRuleElementMatch extendedContainerMatch = containerMatch.copy(); + RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch); + + AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, nextOne, stream); + + doMatch(coveredByWildCard, extendedMatch, extendedContainerMatch, annotation == null, stream, + crowd); + if (extendedMatch.matched()) { + nextElement.continueMatch(after, endAnchor, extendedMatch, ruleApply, + extendedContainerMatch, sideStepOrigin, nextElement, stream, crowd); + List<RuleElementMatch> nextList = extendedContainerMatch.getInnerMatches().get(nextElement); + if (nextList == null || nextList.isEmpty()) { + moveOn(after, iterator); + } else { + doneHere = true; + } + } else { + // conditions of wildcard element did not match, try the next possible anchor for the + // next rule element + moveOn(after, iterator); + } + } + } + + private FSIterator<AnnotationFS> getIterator(boolean after, AnnotationFS annotation, + RuleElement nextElement, Type defaultType, TextMarkerStream stream) { + CAS cas = stream.getCas(); + FSIterator<AnnotationFS> iterator = null; + if (defaultType == null) { + TextMarkerRuleElement re = (TextMarkerRuleElement) nextElement; + TextMarkerMatcher matcher = re.getMatcher(); + if (matcher instanceof TextMarkerTypeMatcher) { + TextMarkerTypeMatcher typeMatcher = (TextMarkerTypeMatcher) re.getMatcher(); + List<Type> types = typeMatcher.getTypes(parent, stream); + Type type = types.get(0); + if (annotation == null) { + iterator = cas.getAnnotationIndex(type).iterator(); + } else { + iterator = cas.getAnnotationIndex(type).iterator(annotation); + } + } else if (matcher instanceof TextMarkerDisjunctiveMatcher) { + List<Type> types = matcher.getTypes(parent, stream); + iterator = getIteratorForDisjunctive(cas, types, after, annotation, stream); + } else { + // should not happen + } + } else { + if (annotation == null) { + iterator = cas.getAnnotationIndex(defaultType).iterator(); + } else { + iterator = cas.getAnnotationIndex(defaultType).iterator(annotation); + } + } + return iterator; + } + + private void tryWithNextLiteral(boolean after, AnnotationFS annotation, + TextMarkerRuleElement nextElement, RuleMatch ruleMatch, RuleApply ruleApply, + ComposedRuleElementMatch containerMatch, TextMarkerRuleElement sideStepOrigin, + TextMarkerStream stream, InferenceCrowd crowd) { + TextMarkerLiteralMatcher matcher = (TextMarkerLiteralMatcher) nextElement.getMatcher(); + StringExpression expression = matcher.getExpression(); + String stringValue = expression.getStringValue(parent); + AnnotationFS documentAnnotation = stream.getDocumentAnnotation(); + int delta = documentAnnotation.getBegin(); + String document = documentAnnotation.getCoveredText(); + int pointer = 0; + if(annotation != null) { + pointer = annotation.getEnd() - delta; + } + int indexOf = 0; + boolean doneHere = false; + // TODO matching direction not included in document.indexOf(). Need another method here + while (!doneHere && (indexOf = document.indexOf(stringValue, pointer)) < document.length()) { + if (indexOf < 0) { + // can't match, the next next element will see it. + nextElement.continueMatch(after, annotation, ruleMatch, ruleApply, containerMatch, + sideStepOrigin, null, stream, crowd); + doneHere = true; + break; + } + TextMarkerBasic anchor = stream.getAnchor(after, indexOf); + TextMarkerBasic endAnchor = stream.getAnchor(!after, indexOf); + ComposedRuleElementMatch extendedContainerMatch = containerMatch.copy(); + RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch); + AnnotationFS coveredByWildCard = getCoveredByWildCard(after, annotation, anchor, stream); + doMatch(coveredByWildCard, extendedMatch, extendedContainerMatch, annotation == null, stream, + crowd); + if (extendedMatch.matched()) { + nextElement.continueMatch(after, endAnchor, extendedMatch, ruleApply, + extendedContainerMatch, sideStepOrigin, nextElement, stream, crowd); + List<RuleElementMatch> nextList = extendedContainerMatch.getInnerMatches().get(nextElement); + if (nextList == null || nextList.isEmpty()) { + pointer = getNextPointer(after, anchor); + } else { + doneHere = true; + } + } else { + pointer = getNextPointer(after, anchor); + } + } + } + + private int getNextPointer(boolean after, AnnotationFS anchor) { + if (after) { + return anchor.getEnd(); + } else { + return anchor.getBegin(); + } + } + + private FSIterator<AnnotationFS> getIteratorForDisjunctive(CAS cas, List<Type> types, + boolean after, AnnotationFS annotation, TextMarkerStream stream) { + ConstraintFactory cf = cas.getConstraintFactory(); + FSTypeConstraint typeConstraint = cf.createTypeConstraint(); + for (Type each : types) { + typeConstraint.add(each); + } + FSIterator<AnnotationFS> windowIt = cas.getAnnotationIndex().subiterator( + stream.getDocumentAnnotation()); + FSIterator<AnnotationFS> iterator = cas.createFilteredIterator(windowIt, typeConstraint); + if (annotation != null) { + iterator.moveTo(annotation); + if (!after) { + iterator.moveToPrevious(); + } + } else { + if (after) { + iterator.moveToFirst(); + } else { + iterator.moveToLast(); + } + } + + return iterator; + } + + private void moveOn(boolean after, FSIterator<AnnotationFS> iterator) { + if (after) { + iterator.moveToNext(); + } else { + iterator.moveToPrevious(); + } + } + + private AnnotationFS getCoveredByWildCard(boolean after, AnnotationFS annotation, + AnnotationFS nextOne, TextMarkerStream stream) { + AnnotationFS afs = null; + CAS cas = stream.getCas(); + Type type = cas.getAnnotationType(); + + int lastBegin = 0; + int lastEnd = 0; + if (annotation != null) { + if (after) { + lastBegin = annotation.getBegin(); + lastEnd = annotation.getEnd(); + } else { + lastBegin = annotation.getBegin(); + lastEnd = annotation.getEnd(); + // TODO refactor code below + } + } else { + // TODO refactor code below + } + + if (nextOne == null) { + AnnotationFS documentAnnotation = stream.getDocumentAnnotation(); + if (after) { + afs = cas.createAnnotation(type, lastEnd, documentAnnotation.getEnd()); + } else { + afs = cas.createAnnotation(type, documentAnnotation.getBegin(), lastBegin); + } + } else { + if (after) { + afs = cas.createAnnotation(type, lastEnd, nextOne.getBegin()); + } else { + afs = cas.createAnnotation(type, nextOne.getEnd(), lastBegin); + } + } + return afs; + } + + private void doMatch(AnnotationFS annotation, RuleMatch ruleMatch, + ComposedRuleElementMatch containerMatch, boolean ruleAnchor, TextMarkerStream stream, + InferenceCrowd crowd) { + RuleElementMatch result = new RuleElementMatch(this, containerMatch); + result.setRuleAnchor(ruleAnchor); + List<EvaluatedCondition> evaluatedConditions = new ArrayList<EvaluatedCondition>( + conditions.size()); + boolean base = true; + List<AnnotationFS> textsMatched = new ArrayList<AnnotationFS>(1); + if (base) { + for (AbstractTextMarkerCondition condition : conditions) { + crowd.beginVisit(condition, null); + EvaluatedCondition eval = condition.eval(annotation, this, stream, crowd); + crowd.endVisit(condition, null); + evaluatedConditions.add(eval); + } + } + if (annotation != null) { + textsMatched.add(annotation); + } + result.setMatchInfo(base, textsMatched, evaluatedConditions); + ruleMatch.setMatched(ruleMatch.matched() && result.matched()); + List<RuleElementMatch> rems = new ArrayList<RuleElementMatch>(); + rems.add(result); + ruleMatch.processMatchInfo(this, rems, stream); + } + + public void continueOwnMatch(boolean after, AnnotationFS annotation, RuleMatch ruleMatch, + RuleApply ruleApply, ComposedRuleElementMatch containerMatch, + TextMarkerRuleElement sideStepOrigin, RuleElement entryPoint, TextMarkerStream stream, + InferenceCrowd crowd) { + // won't happen + } + + public Collection<AnnotationFS> getAnchors(TextMarkerStream symbolStream) { + // shouldn't happen + // really? what about anchoring at start? + return Collections.emptyList(); + } + + public int estimateAnchors(TextMarkerStream stream) { + return Integer.MAX_VALUE; + } + + public String toString() { + return "#" + (conditions.isEmpty() ? "" : "(" + conditions.toString() + ")" + "\\n") + + (actions.isEmpty() ? "" : "{" + actions.toString() + "}"); + } + +} Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/verbalize/ScriptVerbalizer.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/verbalize/ScriptVerbalizer.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/verbalize/ScriptVerbalizer.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/main/java/org/apache/uima/textmarker/verbalize/ScriptVerbalizer.java Fri Mar 22 16:45:30 2013 @@ -38,6 +38,7 @@ import org.apache.uima.textmarker.rule.T import org.apache.uima.textmarker.rule.TextMarkerMatcher; import org.apache.uima.textmarker.rule.TextMarkerRule; import org.apache.uima.textmarker.rule.TextMarkerRuleElement; +import org.apache.uima.textmarker.rule.WildCardRuleElement; import org.apache.uima.textmarker.rule.quantifier.MinMaxGreedy; import org.apache.uima.textmarker.rule.quantifier.MinMaxReluctant; import org.apache.uima.textmarker.rule.quantifier.NormalQuantifier; @@ -107,6 +108,8 @@ public class ScriptVerbalizer { } else if (re instanceof TextMarkerRuleElement) { TextMarkerRuleElement tmre = (TextMarkerRuleElement) re; result.append(verbalizeMatcher(tmre)); + } else if(re instanceof WildCardRuleElement) { + result.append("#"); } result.append(verbalizeQuantifier(quantifier)); Modified: uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/AllTests.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/AllTests.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/AllTests.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/AllTests.java Fri Mar 22 16:45:30 2013 @@ -41,7 +41,8 @@ import org.junit.runners.Suite.SuiteClas AllActionsTest.class, AllConditionsTest.class, CurrentCountTest.class, PartOfTest.class, PositionTest.class, DefaultSeederTest.class, ConditionVerbalizerTest.class, ActionVerbalizerTest.class, ExpressionVerbalizerTest.class, HtmlAnnotatorTest.class, - HtmlConverterTest.class, EmptyDocumentTest.class, TextMarkerModifierTest.class, RegExpRuleTest.class }) + HtmlConverterTest.class, EmptyDocumentTest.class, TextMarkerModifierTest.class, + RegExpRuleTest.class, WildCardTest.class }) public class AllTests { } Added: uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/WildCardTest.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/WildCardTest.java?rev=1459894&view=auto ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/WildCardTest.java (added) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/test/java/org/apache/uima/textmarker/WildCardTest.java Fri Mar 22 16:45:30 2013 @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.uima.textmarker; + +import static org.junit.Assert.assertEquals; + +import org.apache.uima.cas.CAS; +import org.apache.uima.cas.FSIterator; +import org.apache.uima.cas.Type; +import org.apache.uima.cas.text.AnnotationFS; +import org.apache.uima.cas.text.AnnotationIndex; +import org.junit.Test; + +public class WildCardTest { + + @Test + public void test() { + String name = this.getClass().getSimpleName(); + String namespace = this.getClass().getPackage().getName().replaceAll("\\.", "/"); + CAS cas = null; + try { + cas = TextMarkerTestUtils.process(namespace + "/" + name + ".tm", namespace + "/" + name + + ".txt", 50); + } catch (Exception e) { + e.printStackTrace(); + assert (false); + } + Type t = null; + AnnotationIndex<AnnotationFS> ai = null; + FSIterator<AnnotationFS> iterator = null; + + t = TextMarkerTestUtils.getTestType(cas, 1); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals(cas.getDocumentText().length(), iterator.next().getCoveredText().length()); + + t = TextMarkerTestUtils.getTestType(cas, 2); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The", iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 3); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The TextMarker language is an imperative rule language extended with scripting elements.", iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 4); + ai = cas.getAnnotationIndex(t); + assertEquals(8, ai.size()); + + t = TextMarkerTestUtils.getTestType(cas, 5); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The TextMarker language is an imperative rule language extended with scripting elements", iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 6); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The TextMarker language is an imperative rule language extended with scripting elements", iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 7); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals(cas.getDocumentText(), iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 8); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals(cas.getDocumentText(), iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 9); + ai = cas.getAnnotationIndex(t); + assertEquals(2, ai.size()); + + t = TextMarkerTestUtils.getTestType(cas, 10); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The TextMarker language is an imperative rule language extended with scripting elements", iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 11); + ai = cas.getAnnotationIndex(t); + assertEquals(9, ai.size()); + + t = TextMarkerTestUtils.getTestType(cas, 12); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The TextMarker language is an imperative rule language extended with scripting elements.", iterator.next().getCoveredText()); + + t = TextMarkerTestUtils.getTestType(cas, 13); + ai = cas.getAnnotationIndex(t); + assertEquals(8, ai.size()); + + t = TextMarkerTestUtils.getTestType(cas, 14); + ai = cas.getAnnotationIndex(t); + assertEquals(1, ai.size()); + iterator = ai.iterator(); + assertEquals("The TextMarker language is an imperative rule language extended with scripting elements.", iterator.next().getCoveredText()); + + + if (cas != null) { + cas.release(); + } + + } +} Added: uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.tm URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.tm?rev=1459894&view=auto ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.tm (added) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.tm Fri Mar 22 16:45:30 2013 @@ -0,0 +1,24 @@ +PACKAGE org.apache.uima; + + +DECLARE T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; + + +CW{-PARTOF(T1)} #{-> MARK(T1,1,2)}; +Document{-> DYNAMICANCHORING(true)}; +#{-PARTOF(T2)-> MARK(T2,1,2)} CW; +#{-PARTOF(T3) -> MARK(T3,1,2)} PERIOD; +Document{-> DYNAMICANCHORING(false)}; +CW{-PARTOF(T4)} #{-> MARK(T4,1,2,3)} PERIOD; +#{-> MARK(T5)} PERIOD; +Document{-> DYNAMICANCHORING(true)}; +#{-PARTOF(T6) -> MARK(T6)} PERIOD; +Document{-> DYNAMICANCHORING(false)}; +#{-> MARK(T7)}; +# #{-> MARK(T8)}; +"Text" "Marker" #{-> MARK(T9)} "."; +#{-PARTOF(T10)-> MARK(T10)} "."; +CW{-PARTOF(T11)} #{-> MARK(T11,1,2,3)} (PERIOD | COLON); +#{-PARTOF(T12) -> MARK(T12,1,2)} (PERIOD | COLON); +CW{-PARTOF(T13)} #{-> MARK(T13,1,2,3)} (SW PERIOD); +CW{-PARTOF(T14)} #{-> MARK(T14,1,2,3)} ("elements" PERIOD); \ No newline at end of file Added: uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.txt URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.txt?rev=1459894&view=auto ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.txt (added) +++ uima/sandbox/textmarker/trunk/textmarker-core/src/test/resources/org/apache/uima/textmarker/WildCardTest.txt Fri Mar 22 16:45:30 2013 @@ -0,0 +1,11 @@ +The TextMarker language is an imperative rule language extended with scripting elements. +A TextMarker rule defines a pattern of annotations with additional conditions. If this +pattern applies, then the actions of the rule are performed on the matched annotations. +A rule is composed of a sequence of rule elements and a rule element essentially consists +of four parts: A matching condition, an optional quantifier, a list of conditions and a +list of actions. The matching condition is typically a type of an annotation by which the +rule element matches on the covered text of one of those annotations. The quantifier +specifies, whether it is necessary that the rule element successfully matches and how often +the rule element may match. The list of conditions specifies additional constraints that +the matched text or annotations need to fulfill. The list of actions defines the +consequences of the rule and often creates new annotations or modifies existing annotations. \ No newline at end of file Modified: uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerLexer.g URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerLexer.g?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerLexer.g (original) +++ uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerLexer.g Fri Mar 22 16:45:30 2013 @@ -511,6 +511,9 @@ LESSEQUAL : '<=' ; GREATEREQUAL : '>=' ; + +WILDCARD : '#' ; + WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} ; Modified: uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerParser.g URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerParser.g?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerParser.g (original) +++ uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/antlr3/org/apache/uima/textmarker/ide/core/parser/TextMarkerParser.g Fri Mar 22 16:45:30 2013 @@ -617,7 +617,33 @@ ruleElement returns [Expression re = nul re1 = ruleElementType {re = re1;} | re2 = ruleElementLiteral {re = re2;} | re3 = ruleElementComposed {re = re3;} + | re4 = ruleElementWildCard {re = re4;} ; + +ruleElementWildCard returns [TextMarkerRuleElement re = null] +@init{ +List<TextMarkerCondition> dummyConds = new ArrayList<TextMarkerCondition>(); +} + : + w = WILDCARD + (LCURLY + { + + dummyConds.add(ConditionFactory.createEmptyCondition(input.LT(1))); + } + c = conditions? + { + if(c==null) { + c = dummyConds; + } + } + (THEN a = actions)? end = RCURLY)? + { + + re = scriptFactory.createRuleElement(w,c,a,end);} + + ; + ruleElementComposed returns [ComposedRuleElement re = null] @init{ Modified: uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/TextMarkerKeywords.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/TextMarkerKeywords.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/TextMarkerKeywords.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/TextMarkerKeywords.java Fri Mar 22 16:45:30 2013 @@ -39,7 +39,7 @@ public class TextMarkerKeywords implemen private static String[] basic = { "ALL", "ANY", "AMP", "BREAK", "W", "NUM", "PM", "Document", "MARKUP", "SW", "CW", "CAP", "PERIOD", "NBSP", "SENTENCEEND", "COLON", "COMMA", "SEMICOLON", - "WS", "_", "SPACE", "SPECIAL", "EXCLAMATION", "QUESTION", }; + "WS", "_", "SPACE", "SPECIAL", "EXCLAMATION", "QUESTION", "#" }; private static String[] booleanFunction = { "true", "false" }; Modified: uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/parser/DLTKTextMarkerErrorReporter.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/parser/DLTKTextMarkerErrorReporter.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/parser/DLTKTextMarkerErrorReporter.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/core/parser/DLTKTextMarkerErrorReporter.java Fri Mar 22 16:45:30 2013 @@ -15,7 +15,7 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. -*/ + */ package org.apache.uima.textmarker.ide.core.parser; @@ -34,7 +34,6 @@ import org.eclipse.dltk.compiler.problem import org.eclipse.dltk.compiler.problem.IProblemReporter; import org.eclipse.dltk.compiler.problem.ProblemSeverities; - /** * * @see org.eclipse.dltk.p y thon.internal.core.parsers.DLTKP y thonErrorReporter @@ -70,11 +69,9 @@ public class DLTKTextMarkerErrorReporter if (index < 0) { index = re.index; TokenStream tokenStream = parser.getTokenStream(); - try { + if (index > 0) { token = tokenStream.get(index - 1); line = token.getLine(); - } catch (ArrayIndexOutOfBoundsException e) { - e.printStackTrace(); } } @@ -91,8 +88,8 @@ public class DLTKTextMarkerErrorReporter String errorPrefix = ""; - // - // + // + // if (re instanceof NoViableAltException) { NoViableAltException nvae = (NoViableAltException) re; errorPrefix = "Syntax error: "; @@ -278,8 +275,8 @@ public class DLTKTextMarkerErrorReporter // reporter.handle(CompilerOptions.OFFSET, messages, messages, // st, et); DefaultProblem defaultProblem = new DefaultProblem("", "Type not defined in this script: " - + convert.getText(), 0, new String[] {}, ProblemSeverities.Warning, st, et, re.token - .getLine()); + + convert.getText(), 0, new String[] {}, ProblemSeverities.Warning, st, et, + re.token.getLine()); if (!problems.contains(defaultProblem)) { reporter.reportProblem(defaultProblem); problems.add(defaultProblem); Modified: uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/AbstractFactory.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/AbstractFactory.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/AbstractFactory.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/AbstractFactory.java Fri Mar 22 16:45:30 2013 @@ -128,6 +128,12 @@ public abstract class AbstractFactory { } } + protected static final void setMinBegin(int[] bounds, Token begin) { + if (begin != null && bounds != null && bounds.length >= 1) { + bounds[0] = Math.min(bounds[0], getBounds(begin)[1]); + } + } + /** * Applies start/end positions of <code>Token token</code> to <code>Node node</code> * Modified: uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/ScriptFactory.java URL: http://svn.apache.org/viewvc/uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/ScriptFactory.java?rev=1459894&r1=1459893&r2=1459894&view=diff ============================================================================== --- uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/ScriptFactory.java (original) +++ uima/sandbox/textmarker/trunk/textmarker-ep-ide/src/main/java/org/apache/uima/textmarker/ide/parser/ast/ScriptFactory.java Fri Mar 22 16:45:30 2013 @@ -105,6 +105,20 @@ public class ScriptFactory extends Abstr conditions, actions); } + public TextMarkerRuleElement createRuleElement(Token w, List<TextMarkerCondition> c, + List<TextMarkerAction> a, Token end) { + int bounds[] = getSurroundingBounds(null, c, a); + setMinBegin(bounds, w); + filterNullObjects(c); + filterNullObjects(a); + return new TextMarkerRuleElement(bounds[0], bounds[1], null, null, + c, a); + } + + + + + /** * Creates Root-Block. * @@ -181,4 +195,6 @@ public class ScriptFactory extends Abstr } } + + }