!7
cmodule TopDownParsing > DynSCP {
switchable S input = "Bob paid for Charlie 's college education";
TryPatterns root;
transient S selectedGrouped;
transient ReliableSingleThread rstProcessInput = dm_rstWithPreDelay(this, 500, r processInput);
// Tree has 2 types of nodes: composite and options
abstract class Base {
L children;
L children() { ret children; }
abstract S grouped();
}
// composite node
class AppliedPattern > Base {
S pattern;
LS arguments;
L children() {
if (children == null)
children = map(arguments, a -> new TryPatterns(a));
ret children;
}
toString { ret stdToStringWithFields(this, 'pattern, 'arguments); }
S grouped() {
ret format3_round(pattern, toStringArray(arguments));
}
}
// options node (try different patterns)
class TryPatterns > Base {
S input;
*() {}
*(S *input) {}
L children() {
if (children == null) {
children = new L;
for (S pat : patterns())
for (LS arguments : matchesToStringLists(flexMatchIC_all(pat, input)))
children.add(setAll(new AppliedPattern, pattern := pat, +arguments));
}
ret children;
}
toString { ret stdToStringWithFields(this, 'input) + ", n=" + l(children()); }
S grouped() {
ret empty(children()) ? null : first(children).grouped();
}
}
start {
dm_watchFieldAndNow input(rstProcessInput);
}
JComponent visualize2() {
JTree tree = jDynamicTree(root, x -> x.children());
onTreeSelectionChanged(tree, r {
Base base = cast jtree_selectedUserObject(tree);
setField(selectedGrouped := base == null ? null : base.grouped());
});
ret northCenterAndSouthWithMargins(
jCenteredSection("Input", dm_centeredTextField input()),
tree,
jCenteredSection("Grouped", dm_label selectedGrouped()));
}
LS patterns() { ret dm_getUnclearList("patterns"); }
// API
void processInput {
setField(root := parse(input));
revisualize2();
}
TryPatterns parse(S s) {
ret new TryPatterns(s);
}
TryPatterns root() { ret root; }
}