X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FStateNode.java;h=768d8bfb6c7397c26eb818bd03f84194f6c6dd0a;hp=af1a3e9c20f60139e71c856cdfc2a022150eaace;hb=52e7a254d32940210e0efce25e622d6266fc7f37;hpb=d96df56ee69e62c4d4d6dfe3786ea4853e5120eb diff --git a/src/edu/berkeley/sbp/StateNode.java b/src/edu/berkeley/sbp/StateNode.java index af1a3e9..768d8bf 100644 --- a/src/edu/berkeley/sbp/StateNode.java +++ b/src/edu/berkeley/sbp/StateNode.java @@ -15,11 +15,10 @@ final class StateNode extends Node implements Invokable { + private boolean fromEmptyReduction; 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; } @@ -44,39 +43,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().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) 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 { + Input.Region region = pred.phase().getLocation().createRegion(target.getLocation()); + new Reduction(pred, r, r.rewrite(region), 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; + this.fromEmptyReduction = pred!=null && pred.reduction()!=null && pred.reduction().numPops()==0; if (phase.hash.get(state, pred.phase()) != null) throw new Error("severe problem!"); phase.hash.put(state, pred.phase(), this); addPred(pred); @@ -95,7 +91,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); } }