+ public Sequence makeSequence(Production p) {
+ return Sequence.rewritingSequence(new TargetReducer(p), p.elements, p.labels, p.drops);
+ }
+ public abstract Object plant(Object[] fields, int[] map);
+ public class TargetReducer implements Reducer {
+ private Production p;
+ private int[] map;
+ public TargetReducer(Production p) {
+ this.p = p;
+ this.map = buildSequence(p);
+ }
+ public String toString() { return "reducer-"+Target.this; }
+ public Object reduce(Tree t) {
+ Object[] objects = new Object[t.numChildren()];
+ for(int i=0; i<t.numChildren(); i++) {
+ Tree tc = t.child(i);
+ if (tc.head() != null && tc.head() instanceof Reducer)
+ objects[i] = ((Reducer)tc.head()).reduce(tc);
+ else if (tc.numChildren() == 0)
+ objects[i] = tc.head();
+ else if (t.numChildren()==1) {
+ //FIXME: EVIL!!
+ objects[i] = reduce(t.child(0));
+ } else {
+ System.err.println("FIXME: don't know what to do about " + tc);
+ objects[i] = null;
+ }
+ }
+ return plant(objects, map);
+ }
+ }
+ }
+
+ public static interface Reducer {
+ public Object reduce(Tree t);