X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FParser.java;h=65f3dc3e9e3f17b80be3d03950ffc9d22ddc0901;hp=58d0bc2a217118aaeb174974af72fc4a13dfd02c;hb=b0ec1efcb13eceb539f9cd033a0d2908fc2be27a;hpb=7fbee73b4dd985cb5b217ed297710c00fd9d7004 diff --git a/src/edu/berkeley/sbp/Parser.java b/src/edu/berkeley/sbp/Parser.java index 58d0bc2..65f3dc3 100644 --- a/src/edu/berkeley/sbp/Parser.java +++ b/src/edu/berkeley/sbp/Parser.java @@ -134,7 +134,7 @@ public abstract class Parser { Walk.Follow wf = new Walk.Follow(top.empty(), p.owner(), all_elements, cache); Reduction red = new Reduction(p); state.reductions.put(wf.walk(p.owner()), red); - if (wf.includesEof()) state.eofReductions.add(red, true); + if (wf.includesEof()) state.eofReductions.add(red); } // if the element following this position is an atom, copy the corresponding @@ -168,14 +168,14 @@ public abstract class Parser { } */ - public final int idx = master_state_idx++; + public final int idx = master_state_idx++; private final HashSet hs; private transient HashMap gotoSetNonTerminals = new HashMap(); private transient TopologicalBag gotoSetTerminals = new TopologicalBag(); private TopologicalBag reductions = new TopologicalBag(); - private FastSet eofReductions = new FastSet(); + private HashSet eofReductions = new HashSet(); private TopologicalBag shifts = new TopologicalBag(); private boolean accept = false; @@ -184,7 +184,7 @@ public abstract class Parser { public boolean canShift(Token t) { return shifts.contains(t); } public Iterable getShifts(Token t) { return shifts.get(t); } public boolean isAccepting() { return accept; } - public Iterable getReductions(Token t) { return reductions.get(t); } + public Iterable getReductions(Token t) { return t==null ? eofReductions : reductions.get(t); } public Iterable getEofReductions() { return eofReductions; } public Iterator iterator() { return hs.iterator(); } @@ -310,12 +310,24 @@ public abstract class Parser { this.holder = new Forest[numPop]; } public String toString() { return "[reduce " + position + "]"; } - public Forest reduce(Forest f, GSS.Phase.Node parent, GSS.Phase.Node onlychild, GSS.Phase target, Forest rex) { - holder[numPop-1] = f; - return reduce(parent, numPop-2, rex, onlychild, target); + + public Forest reduce(GSS.Phase.Node parent) { + if (numPop==0) return finish(parent, zero(), parent.phase()); + return reduce(parent, numPop-1, null, parent.phase()); } - public Forest reduce(GSS.Phase.Node parent, GSS.Phase.Node onlychild, GSS.Phase target, Forest rex) { - return reduce(parent, numPop-1, rex, onlychild, target); + + public Forest reduce(GSS.Phase.Node parent, GSS.Phase.Node onlychild) { + if (numPop<=0) throw new Error("called wrong form of reduce()"); + int pos = numPop-1; + holder[pos] = parent.pending(); + Forest rex = null; + if (pos==0) { + if (rex==null) { + System.arraycopy(holder, 0, position.holder, 0, holder.length); + rex = position.rewrite(parent.phase().getLocation()); + } + } + return reduce(onlychild, pos-1, rex, parent.phase()); } private Forest zero = null; @@ -326,25 +338,23 @@ public abstract class Parser { } // FIXME: this could be more elegant and/or cleaner and/or somewhere else - private Forest reduce(GSS.Phase.Node parent, int pos, Forest rex, GSS.Phase.Node onlychild, GSS.Phase target) { - if (pos>=0) holder[pos] = parent.pending(); - if (pos<=0 && rex==null) { + private Forest reduce(GSS.Phase.Node parent, int pos, Forest rex, GSS.Phase target) { + if (pos<0) return finish(parent, rex, target); + holder[pos] = parent.pending(); + if (pos==0 && rex==null) { System.arraycopy(holder, 0, position.holder, 0, holder.length); rex = position.rewrite(target.getLocation()); } - if (pos >=0) { - if (onlychild != null) - reduce(onlychild, pos-1, rex, null, target); - else - for(GSS.Phase.Node child : parent.parents()) - reduce(child, pos-1, rex, null, target); - } else { - State state = parent.state.gotoSetNonTerminals.get(position.owner()); - if (state!=null) - target.newNode(parent, rex, state, numPop<=0, parent.phase); - } + for(GSS.Phase.Node child : parent.parents()) + reduce(child, pos-1, rex, target); return rex; } + private Forest finish(GSS.Phase.Node parent, Forest result, GSS.Phase target) { + State state = parent.state.gotoSetNonTerminals.get(position.owner()); + if (state!=null) + target.newNode(parent, result, state, numPop<=0, parent.phase()); + return result; + } } }