X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FStateNode.java;h=c67b1af021926ae64257e34330b855a7b45790b4;hp=af1a3e9c20f60139e71c856cdfc2a022150eaace;hb=HEAD;hpb=d96df56ee69e62c4d4d6dfe3786ea4853e5120eb;ds=sidebyside diff --git a/src/edu/berkeley/sbp/StateNode.java b/src/edu/berkeley/sbp/StateNode.java index af1a3e9..c67b1af 100644 --- a/src/edu/berkeley/sbp/StateNode.java +++ b/src/edu/berkeley/sbp/StateNode.java @@ -16,12 +16,14 @@ final class StateNode implements Invokable { private final Parser.Table.State state; - private boolean fromEmptyReduction; /** which GSS.Phase this StateNode belongs to */ - public Iterator iterator() { return predecessors.iterator(); } public Parser.Table.State state() { return state; } public boolean isDoomedState() { return state.doomed; } + public boolean hasPathToRoot() { + if (state.doomed) return false; + return super.hasPathToRoot(); + } public void check() { if (destroyed) return; @@ -31,10 +33,10 @@ final class StateNode // - be on the frontier or // - have a non-doomed node closer to the frontier than themself if (phase().isFrontier()) dead = false; - else for(ResultNode r : successors) + else for(ResultNode r : successors()) if (state.doomed) { if (r.hasSuccessors()) { dead = false; break; } } else { if (r.hasNonDoomedSuccessors()) { dead = false; break; } } - dead |= predecessors.size()==0; + dead |= !hasPredecessors(); if (!dead) return; if (phase() != null && phase().hash != null) phase().hash.remove(state, predecessorPhase()); @@ -44,39 +46,36 @@ final class StateNode public final void invoke(Pos r, ResultNode only, Object o) { boolean emptyProductions = only==null; if (emptyProductions != (r.numPops()==0)) return; - if (r.numPops()!=0) reduce(r, r.numPops()-1, phase(), only); - else { + if (r.numPops()==0) { Input.Region region = phase().getLocation().createRegion(phase().getLocation()); phase().newNodeFromReduction(r.rewrite(region), r, this); + } else { + // never start reductions at a node that was created via a right-nulled rule + if (only.reduction() != null && only.reduction().numPops()==0) return; + reduce(r, r.numPops()-1, phase(), only); } } private void reduce(Pos r, int pos, GSS.Phase target, ResultNode only) { - for(ResultNode res : predecessors) + for(ResultNode res : this) if (only == null || res == only) - for(StateNode pred : res) - reduce2(r, pos, target, pred, res.getForest()); + for(StateNode pred : res) { + Forest[] holder = r.holder; + Forest old = pos >= holder.length ? null : holder[pos]; + if (pos < holder.length) holder[pos] = res.getForest(); + if (pos>0) pred.reduce(r, pos-1, target, null); + else new Reduction(pred, r, + pred.hasPathToRoot() + ? r.rewrite(pred.phase().getLocation().createRegion(target.getLocation())) + : null, + target); + if (pos < holder.length) holder[pos] = old; + } } - void reduce2(Pos r, int pos, GSS.Phase target, StateNode pred, Forest f) { - Forest[] holder = r.holder; - Forest old = pos >= holder.length ? null : holder[pos]; - if (pos < holder.length) holder[pos] = f; - if (pos>0) pred.reduce(r, pos-1, target, null); - else { - Input.Region region = pred.phase().getLocation().createRegion(target.getLocation()); - new Reduction(pred, r, r.rewrite(region), target); - } - if (pos < holder.length) holder[pos] = old; - } - - StateNode(GSS.Phase phase, Forest f, Pos reduction, StateNode pred, State state, boolean fromEmptyReduction) { - this(phase, new ResultNode(f, reduction, pred), state, fromEmptyReduction); - } - StateNode(GSS.Phase phase, ResultNode pred, State state, boolean fromEmptyReduction) { + StateNode(GSS.Phase phase, ResultNode pred, State state) { super(phase, pred.phase()); this.state = state; - this.fromEmptyReduction = fromEmptyReduction; if (phase.hash.get(state, pred.phase()) != null) throw new Error("severe problem!"); phase.hash.put(state, pred.phase(), this); addPred(pred); @@ -86,7 +85,7 @@ final class StateNode // Add/Remove Successors/Predecessors ////////////////////////////////////////////////////////////////////////////// public void addPred(Forest f, Pos reduction, StateNode pred) { - for(ResultNode r : predecessors) + for(ResultNode r : this) if (r.predecessorsContains(pred)) { r.merge(f); return; @@ -95,7 +94,6 @@ final class StateNode } protected void addPred(ResultNode result) { super.addPred(result); - if (!this.fromEmptyReduction) - state.invokeReductions(phase().getToken(), this, result); + state.invokeReductions(phase().getToken(), this, result); } }