factored exceptions into non-inner classes
[sbp.git] / src / edu / berkeley / sbp / GSS.java
index 1adb8e4..8053ae8 100644 (file)
@@ -24,7 +24,8 @@ class GSS {
     HashSet<Phase.Waiting> tail = new     HashSet<Phase.Waiting>();
     
     /** corresponds to a positions <i>between tokens</i> the input stream; same as Tomita's U_i's */
-    public class Phase implements Invokable<State, Forest, GSS.Phase.Node> {
+    public class Phase implements Invokable<State, Forest, GSS.Phase.Node>, IntegerMappable {
+        public int toInt() { return pos+1; }
 
         /** the token immediately after this phase */
         public  final Token token;
@@ -38,7 +39,7 @@ class GSS {
         public  Forest.Ref finalResult;
 
         /** all nodes, keyed by the value returned by code() */
-        /*private*/ HashMap<Long,Phase.Node> hash;  /* ALLOC */
+        /*private*/ IntPairMap<Phase.Node> hash;  /* ALLOC */
 
         /** the number of nodes in this phase */
         private int numNodes;
@@ -69,7 +70,7 @@ class GSS {
             tail.clear();
             waiting.clear();
             performed.clear();
-            hash = new HashMap<Long,Phase.Node>();
+            hash = new IntPairMap<Phase.Node>();
             good = false;
             closed = false;
             numNodes = 0;
@@ -131,7 +132,10 @@ class GSS {
             ret.append("\n  ");
             ret.append(message);
             HashMap<String,HashSet<String>> errors = new HashMap<String,HashSet<String>>();
-            for(Node n : hash.values()) complain(n, errors, false);
+            for(Node n : hash.values()) {
+                //System.out.println(n.state);
+                complain(n, errors, false);
+            }
             for(String s : errors.keySet()) {
                 ret.append("    while parsing " + yellow(s));
                 HashSet<String> hs = errors.get(s);
@@ -150,10 +154,10 @@ class GSS {
             return ret.toString();
         }
         
-        public boolean isDone() throws Parser.Failed {
+        public boolean isDone() throws ParseFailed {
             if (token != null) return false;
             if (token==null && finalResult==null)
-                throw new Parser.Failed(error(red("unexpected end of file\n")),
+                throw new ParseFailed(error(red("unexpected end of file\n")),
                                         getLocation());
             return true;
         }
@@ -168,7 +172,7 @@ class GSS {
          *  @param start              the earliest part of the input contributing to this node (used to make merging decisions)
          */
         public boolean newNode(Node parent, Forest pending, State state, boolean fromEmptyReduction) {
-            Node p = hash.get(code(state, parent==null?null:parent.phase()));
+            Node p = hash.get(state, parent==null?null:parent.phase());
             if (p != null)  return newNode2(p, parent, pending, state, fromEmptyReduction);
             else            return newNode3(parent, pending, state, fromEmptyReduction);
         }
@@ -269,9 +273,8 @@ class GSS {
                 reducing = true;
                 if (reducing_list==null || reducing_list.length < hash.size())
                     reducing_list = new Phase.Node[hash.size() * 4];
-                Collection<Node> hv = hash.values();
-                hv.toArray(reducing_list);
-                int num = hv.size();
+                hash.toArray(reducing_list);
+                int num = hash.size();
                 for(int i=0; i<num; i++) {
                     Node n = reducing_list[i];
                     n.queueEmptyReductions();
@@ -293,18 +296,21 @@ class GSS {
         class Reset extends RuntimeException { }
 
         public void invoke(State st, Forest result, Node n) {
-            good |= next.newNode(n, result, st, false);
+            boolean ok = next.newNode(n, result, st, false);
+            if (ok && !good) {
+                good = !st.lame();
+                //if (good) System.out.println(st);
+            }
         }
 
         /** perform all shift operations, adding promoted nodes to <tt>next</tt> */
-        public void shift(Phase next, Forest result) throws Parser.Failed {
+        public void shift(Phase next, Forest result) throws ParseFailed {
             if (prev!=null) prev.hash = null;
             this.next = next;
             closed = true;
             Forest res = null;
             boolean ok = false;
             for(Phase.Node n : hash.values()) {
-                //if (n.holder().empty() && pos>0) continue;
                 if (token == null && n.state.isAccepting()) {
                     if (finalResult==null) finalResult = new Forest.Ref();
                     finalResult.merge(n.holder);
@@ -314,10 +320,10 @@ class GSS {
             }
 
             if (!good && token!=null)
-                throw new Parser.Failed(error(red("unexpected character")+" "+purple(token)+" encountered at "+green(getLocation())+"\n"),
+                throw new ParseFailed(error(red("unexpected character")+" "+purple(token)+" encountered at "+green(getLocation())+"\n"),
                                         getLocation());
             if (token==null && finalResult==null)
-                throw new Parser.Failed(error(red("unexpected end of file\n")),
+                throw new ParseFailed(error(red("unexpected end of file\n")),
                                         getLocation());
 
             // this massively improves GC performance
@@ -398,11 +404,10 @@ class GSS {
                 this.fe = fe;
                 this.state = state;
                 this.holder().merge(pending);
-                //if (holder().empty()) throw new Error(holder()+"");
                 Phase start = parent==null ? null : parent.phase();
                 if (parent != null) parents().add(parent, true);
-                if (Phase.this.hash.get(code(state, start)) != null) throw new Error("severe problem!");
-                Phase.this.hash.put(code(state, start), this);
+                if (Phase.this.hash.get(state, start) != null) throw new Error("severe problem!");
+                Phase.this.hash.put(state, start, this);
                 Phase.this.numNodes++;
             }
         }
@@ -415,9 +420,4 @@ class GSS {
         if (a==null || b==null) return false;
         return a.equals(b);
     }
-
-    /** this is something of a hack right now */
-    private static long code(State state, Phase start) {
-        return (((long)state.idx) << 32) | (start==null ? 0 : (start.pos+1));
-    }
 }