// You can either override process(S) or process(ExtS) // depending on whether you need any extra info abstract sclass WordTokRule extends Attractor implements RuleOnTok, RuleOnString { S pattern; // example sentence Set vars; // list of the variable words in the sentence bool debug; transient LS tokPat; // parsed pattern transient SS map; // not null if there is a match *() {} *(S *pattern, S... vars) { this.vars = litciset(vars); } *(S *pattern, Set *vars) {} LS tokPat() { if (tokPat == null) tokPat = wordTok(pattern); ret tokPat; } // override me bool validate() { true; } public bool matches(ExtS s) { ret matches(s); } public bool matches(S s) { process(s); if (map != null && !validate()) map = null; ret matched(); } public void process(ExtS s) { process(s!); } public void process(S s) { process(wordTok(s)); } public void process(LS tok) { map = nullIfContainsKeysOtherThan(gazelle_zipTwoTokenizationsToMap(tokPat(), tok), vars); if (debug) print(pattern + " + " + join(tok) + " => " + map); } bool matched() { ret map != null; } S getVar(S name) { ret getOrKeep(map, name); } void reset { map = null; } }