checkpoint harmony
[sbp.git] / src / edu / berkeley / sbp / Parser.java
index 1a0d307..cbf9b47 100644 (file)
@@ -11,7 +11,7 @@ import java.lang.reflect.*;
 /** a parser which translates streams of Tokens of type T into a Forest<R> */
 public abstract class Parser<T extends Token, R> {
 
-    private final Table pt;
+    public final Table pt;
 
     /** create a parser to parse the grammar with start symbol <tt>u</tt> */
     protected Parser(Union u)  { this.pt = new Table(u, top()); }
@@ -36,17 +36,15 @@ public abstract class Parser<T extends Token, R> {
     public Forest<R> parse(Token.Stream<T> input) throws IOException, Failed {
         GSS gss = new GSS();
         Token.Location loc = input.getLocation();
-        GSS.Phase current = gss.new Phase(null, input.next(1), loc);
-        current.newNode(null, null, pt.start, true);
+        GSS.Phase current = gss.new Phase(null, this, null, input.next(1, 0, 0), loc, null);
+        current.newNode(null, Forest.leaf(null, null), pt.start, true);
         int count = 1;
         for(;;) {
             loc = input.getLocation();
-            GSS.Phase next = gss.new Phase(current, input.next(count), loc);
             current.reduce();
             Forest forest = current.token==null ? null : shiftedToken((T)current.token, loc);
-            current.shift(next, forest);
+            GSS.Phase next = gss.new Phase(current, this, current, input.next(count, gss.resets, gss.waits), loc, forest);
             count = next.hash.size();
-            current.checkFailure();
             if (current.isDone()) return (Forest<R>)current.finalResult;
             current = next;
         }
@@ -55,13 +53,13 @@ public abstract class Parser<T extends Token, R> {
 
     // Exceptions //////////////////////////////////////////////////////////////////////////////
 
-    public static class Failed extends Exception {
+    public static class Failed extends RuntimeException {
         private final Token.Location location;
         private final String         message;
         public Failed() { this("", null); }
         public Failed(String message, Token.Location loc) { this.location = loc; this.message = message; }
         public Token.Location getLocation() { return location; }
-        public String toString() { return message + (location==null ? "" : (" at " + location)); }
+        public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; }
     }
 
     public static class Ambiguous extends RuntimeException {
@@ -83,6 +81,8 @@ public abstract class Parser<T extends Token, R> {
     static class Table extends Walk.Cache {
 
         public final Walk.Cache cache = this;
+
+        public HashMapBag<Position,State> byPosition = new HashMapBag<Position,State>();
         
         private void walk(Element e, HashSet<Element> hs) {
             if (e==null) return;
@@ -161,8 +161,18 @@ public abstract class Parser<T extends Token, R> {
         }
 
         /** a single state in the LR table and the transitions possible from it */
-        public class State implements Comparable<Table.State>, Iterable<Position> {
+
+        public class State implements Comparable<Table.State>, IntegerMappable, Iterable<Position> {
         
+            public int toInt() { return idx; }
+
+            public boolean lame() {
+                for(Position p : this)
+                    for(Position p2 = p; p2!=null; p2=p2.next())
+                        if (p2.isLast() && !p2.owner().lame)
+                            return false;
+                return true;
+            }
             /*
             public boolean isResolvable(Token t) {
                 boolean found = false;
@@ -247,6 +257,7 @@ public abstract class Parser<T extends Token, R> {
                 // register ourselves in the all_states hash so that no
                 // two states are ever created with an identical position set
                 all_states.put(hs, this);
+                for(Position p : hs) byPosition.add(p,this);
 
                 // Step 1a: examine all Position's in this state and compute the mappings from
                 //          sets of follow tokens (tokens which could follow this position) to sets
@@ -309,7 +320,13 @@ public abstract class Parser<T extends Token, R> {
                 }
             }
 
-            public String toString() { return "state["+idx+"]"; }
+            public String toString() {
+                //return "state["+idx+"]";
+                StringBuffer ret = new StringBuffer();
+                ret.append("state["+idx+"]: ");
+                for(Position p : this) ret.append("{"+p+"}  ");
+                return ret.toString();
+            }
 
             public int compareTo(Table.State s) { return idx==s.idx ? 0 : idx < s.idx ? -1 : 1; }
         }
@@ -380,8 +397,9 @@ public abstract class Parser<T extends Token, R> {
             }
             private void finish(GSS.Phase.Node parent, Forest result, GSS.Phase target) {
                 State state = parent.state.gotoSetNonTerminals.get(position.owner());
+                if (result==null) throw new Error();
                 if (state!=null)
-                    target.newNode(parent, result, state, numPop<=0);
+                    target.newNode(parent, result, state, numPop<=0, this);
             }
         }
     }