!7
cmodule TopDownParsing > DynSCP {
switchable S input = "Bob paid for Charlie 's college education";
TryPatterns root;
// Tree has 2 types of nodes: composite and options
class Base {
L children;
L children() { ret children; }
}
// composite node
class AppliedPattern > Base {
S pattern;
LS arguments;
L children() {
lock lock;
if (children == null)
children = map(arguments, a -> new TryPatterns(a));
ret children;
}
toString { ret stdToStringWithFields(this, 'pattern, 'arguments); }
}
// options node (try different patterns)
class TryPatterns > Base {
S input;
*() {}
*(S *input) {}
L children() {
lock lock;
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()); }
}
start {
dm_reloadOnFieldChange input();
parse(input);
//revisualize2();
}
JComponent visualize2() {
ret jDynamicTree(root, x -> x.children());
}
LS patterns() { ret dm_getUnclearList("patterns"); }
// API
TryPatterns parse(S s) {
setField(input := s);
TryPatterns root = new TryPatterns(s);
setField(+root);
ret root;
}
TryPatterns root() { ret root; }
}