!7 cmodule IWantYouToBe > DynPrintLog { abstract class WordTokRule implements RuleOnTok, RuleOnString, Runnable { S pattern; transient LS tokPat; transient SS map; // not null if there is a match Set vars; *() {} *(S *pattern, S... vars) { this.vars = litciset(vars); } LS tokPat() { if (tokPat == null) tokPat = wordTok(pattern); ret tokPat; } public void process(S s) { process(wordTok(s)); } public void process(LS tok) { map = nullIfContainsKeysOtherThan(gazelle_zipTwoTokenizationsToMap(tokPat(), tok), vars); } bool matched() { ret map != null; } S getVar(S name) { ret getOrKeep(map, name); } } class Rule1 extends WordTokRule { *() { super("I want you to be my assistant", "assistant"); } run { emit("I want that {you are my " + getVar("assistant") + "}"); } } A process(A rule, S s) { rule.process(s); ret rule; } start-thread { assertNull(process(new Rule1, "I want you to be his friend").map); new Rule1 r; printStruct(assertEquals(litcimap("assistant", "girl"), process(r, "I want you to be my girl").map)); assertEmitsContainIC(r, "I want that {you are my girl}"); printDone(); } }