major overhaul to institute optimal GSS sharing
[sbp.git] / src / edu / berkeley / sbp / GSS.java
index bf58e64..3876d58 100644 (file)
@@ -24,7 +24,7 @@ class GSS {
     int numReductions = 0;
 
     /** corresponds to a positions <i>between tokens</i> the input stream; same as Tomita's U_i's */
-    class Phase<Tok> implements Invokable<State, Result>, IntegerMappable, GraphViz.ToGraphViz, Iterable<Node> {
+    class Phase<Tok> implements Invokable<State, Node, Forest>, IntegerMappable, GraphViz.ToGraphViz, Iterable<Node> {
 
         // FIXME: right now, these are the performance bottleneck
         private HashMapBag<Integer,Integer>       performed       = new HashMapBag<Integer,Integer>();
@@ -38,15 +38,15 @@ class GSS {
             parser.spin();
             reductionQueue.add(r);
         }
-        public void invoke(State st, Result result) {
+
+        public void invoke(State st, Node pred, Forest f) {
             parser.spin();
-            good |= next.newNode(result, st, false);
+            good |= next.newNode(f, null, pred, st, false);
         }
 
         /** the token immediately after this phase */
         final Tok token;
         final int pos;
-
         public IntPairMap<Node> hash = new IntPairMap<Node>();  /* ALLOC */
         private boolean good = false;
         private Phase next = null;
@@ -58,8 +58,7 @@ class GSS {
 
         public Phase(State startState) throws ParseFailed, IOException {
             this(null, null);
-            Result primordealResult = new Result(null, null, null);
-            newNode(primordealResult, startState, true);
+            newNode(null, null, null, startState, true);
         }
         public Phase(Phase prev, Forest forest) throws ParseFailed, IOException {
             this.location = input.getLocation();
@@ -130,11 +129,11 @@ class GSS {
                         finalResult.merge(r.getForest());
                 }
                 if (token == null) continue;
-                Result result = new Result(f, n, null);
-                n.state().invokeShifts(token, this, result);
+                n.state().invokeShifts(token, this, n, f);
             }
             numNewNodes = next==null ? 0 : next.hash.size();
             viewPos = this.pos;
+
             if (!good && token!=null) {
                 String toks = token+"";
                 if (toks.length()==1 && toks.charAt(0) == edu.berkeley.sbp.chr.CharAtom.left) {
@@ -159,8 +158,8 @@ class GSS {
             return getLocation().createRegion(getNextLocation());
         }
 
-        void newNodeFromReduction(Result result, State state, Pos reduction) {
-            int pos = result.phase().pos;
+        void newNodeFromReduction(Forest f, Pos reduction, Node pred) {
+            int pos = pred.phase().pos;
             for(int s : reduction.hates())
                 if (performed.contains(pos, s))
                     return;
@@ -169,8 +168,9 @@ class GSS {
                     return;
             if (reduction.owner_needed_or_hated() && !performed.contains(pos, reduction.provides()))
                 performed.add(pos, reduction.provides());
+            Parser.Table.State state = (Parser.Table.State)pred.state().gotoSetNonTerminals.get(reduction);
             if (state!=null)
-                newNode(result, state, reduction.numPops()<=0);
+                newNode(f, reduction, pred, state, reduction.numPops()<=0);
         }
 
         /** add a new node (merging with existing nodes if possible)
@@ -180,19 +180,22 @@ class GSS {
          *  @param fromEmptyReduction true iff this node is being created as a result of a reduction of length zero (see GRMLR paper)
          *  @param start              the earliest part of the input contributing to this node (used to make merging decisions)
          */
-        private boolean newNode(Result result, State state, boolean fromEmptyReduction) {
-            Node p = hash.get(state, result.phase());
-            if (p != null) { p.addResult(result); return !state.doomed(); }
+        private boolean newNode(Forest f, Pos reduction, Node pred, State state, boolean fromEmptyReduction) {
+            Node p = pred==null ? null : hash.get(state, pred.phase());
+            if (p != null) {
+                p.addResult(f, reduction, pred);
+                return !state.doomed();
+            }
             do {
                 if (token != null && state.canShift(token)) break;
                 if (state.isAccepting()) break;
                 if (token==null) break;
                 if (!state.canReduce(token)) return false;
             } while(false);
-            Node n = new Node(Phase.this, result, state, fromEmptyReduction);  // ALLOC
+            Node n = new Node(Phase.this, f, reduction, pred, state, fromEmptyReduction);  // ALLOC
             /** FIXME: this null-result can be used to notice bogus/dead states */
             for(Object s : state.conjunctStates)
-                newNode(new Result(null, n, null), (State)s, fromEmptyReduction);
+                newNode(null, null, n, (State)s, fromEmptyReduction);
             return !n.state().doomed();
         }