- // FIXME: explain this
- if (r==null) {
- for(Parser.Table.Reduction r : token==null ? n.state.getEofReductions() : n.state.getReductions(token)) {
- if (r.numPop <= 1) continue;
- r.reduce(n, n2, Phase.this, null);
- }
- } else if (r.numPop==0) { r.reduce(n, n2, n.phase, r.zero());
- } else if (r.numPop==1) {
- // UGLY HACK
- // The problem here is that a "reduction of length 1"
- // performed twice with different values of n2 needs
- // to only create a *single* new result, but must add
- // multiple parents to the node holding that result.
- // The current reducer doesn't differentiate between
- // the next node of an n-pop reduction and the
- // ultimate parent of the last pop, so we need to
- // cache instances here as a way of avoiding
- // recreating them.
-
- Forest ret = n.cache().get(r);
- if (ret != null) r.reduce(n, n2, n.phase, ret);
- else n.cache().put(r, r.reduce(n, n2, n.phase, null));
-
- } else {
- r.reduce(n, n2, Phase.this, null);
- }
- }
-
- // FIXME: this is a PITA
- public int hashCode() { return n.hashCode() ^ (r==null ? 0 : r.hashCode()) ^ (n2==null ? 0 : n2.hashCode()); }
- public boolean equals(Object o) {
- if (o==null) return false;
- if (o==this) return true;
- if (!(o instanceof Reduct)) return false;
- Reduct other = (Reduct)o;
- return equal(r, other.r) && equal(n, other.n) && equal(n2, other.n2);
+ private Node(Node parent, Forest pending, State state) {
+ this.state = state;
+ this.holder().merge(pending);
+ Phase start = parent==null ? null : parent.phase();
+ if (parent != null) parents().add(parent, true);
+ if (Phase.this.hash.get(state, start) != null) throw new Error("severe problem!");
+ Phase.this.hash.put(state, start, this);