preliminary support for serialization of parse tables
[sbp.git] / src / edu / berkeley / sbp / Sequence.java
index eff94a4..d0c3dfd 100644 (file)
@@ -10,9 +10,9 @@ import java.lang.reflect.*;
 import java.lang.ref.*;
 
 /** <font color=green>juxtaposition; zero or more adjacent Elements; can specify a rewriting</font> */
-public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
+public abstract class Sequence implements Iterable<Element>, SequenceOrElement, Serializable {
 
-    protected final Element[] elements;
+    protected transient final Element[] elements;
 
     boolean needed_or_hated = false;
     boolean in_a_union = false;
@@ -26,7 +26,7 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
 
     final Position firstp;
 
-    Atom follow = null;
+    transient Atom follow = null;
 
     private static int global_sernum = 0;
     private int sernum = global_sernum++;
@@ -127,9 +127,9 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
         this.firstp = new Position(this, 0, null);
     }
 
-    abstract Forest epsilonForm(Input.Region loc, Grammar cache);
+    abstract Forest epsilonForm(Input.Region loc);
 
-    protected abstract <T> Forest<T> postReduce(Input.Region loc, Forest<T>[] args, Pos p);
+    protected abstract <T> Forest<T> postReduce(Input.Region loc, Forest<T>[] args, Position p);
 
 
     // Position //////////////////////////////////////////////////////////////////////////////
@@ -137,11 +137,16 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
     static abstract class Pos implements IntegerMappable, Comparable<Pos>, Serializable {
 
         public int ord = -1;
+        private Sequence owner;
+
         public int ord()     { return ord; }
 
         final Forest[] holder;
 
-        Pos(int len) { this.holder = new Forest[len]; }
+        Pos(int len, Sequence owner) {
+            this.owner = owner;
+            this.holder = new Forest[len];
+        }
 
         public abstract int   provides();
         public abstract int[] needs();
@@ -154,11 +159,13 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
         public abstract Pos prev();
         public abstract Pos next();
 
-        abstract Sequence owner();
+        /** the element which produces the sequence to which this Position belongs */
+        public Sequence owner() { return owner; }
+
         abstract Element  element();
 
         public abstract int numPops();
-        public abstract <T> Forest<T> rewrite(Input.Region loc, Grammar cache);
+        public abstract <T> Forest<T> rewrite(Input.Region loc);
     }
 
     /** the imaginary position before or after an element of a sequence; corresponds to an "LR item" */
@@ -171,18 +178,15 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
                 public int[] hates();
                 public boolean            owner_needed_or_hated();
                 public int numPops();
-                public <T> Forest<T> rewrite(Input.Region loc, Grammar cache)
+                public <T> Forest<T> rewrite(Input.Region loc)
             };
         }
         */
-        public int ord = -1;
-        public int ord()     { return ord; }
         public int numPops() { return pos; }
 
                 final     int      pos;
         private final     Position next;
         private final     Position prev;
-        private transient Sequence owner;
 
         public int     provides() { return owner().sernum; }
         public int[]   needs() { return owner().needs_int(); }
@@ -190,8 +194,7 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
         public boolean owner_needed_or_hated() { return owner().needed_or_hated; }
         
         private Position(Sequence owner, int pos, Position prev) {
-            super(owner.elements.length);
-            this.owner    = owner;
+            super(owner.elements.length,owner);
             this.pos      = pos;
             this.next     = pos==owner.elements.length ? null : new Position(owner, pos+1, this);
             this.prev     = prev;
@@ -207,9 +210,6 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
         /** the element immediately after this Position, or null if this is the last Position */
         public Element  element() { return pos>=owner().elements.length ? null : owner().elements[pos]; }
 
-        /** the element which produces the sequence to which this Position belongs */
-        public Sequence owner() { return owner; }
-
         /** the next Position (the Position after <tt>this.element()</tt>) */
         public Position next() { return next; }
 
@@ -220,14 +220,18 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
 
         // Position /////////////////////////////////////////////////////////////////////////////////
 
-        public final <T> Forest<T> rewrite(Input.Region loc, Grammar cache) {
-            if (this==firstp()) epsilonForm(loc, cache);
+        public final <T> Forest<T> rewrite(Input.Region loc) {
+            if (isFirst()) return owner().epsilonForm(loc);
             for(int i=0; i<pos; i++) if (holder[i]==null) throw new Error("realbad " + i);
-            for(int i=pos; i<elements.length; i++) {
-                if (holder[i]==null) holder[i] = ((Union)elements[i]).epsilonForm(loc, cache);
+            Position p = this;
+            for(int i=pos; p!=null && p.next()!=null; p=p.next(), i++) {
+                if (holder[i]==null)
+                    holder[i] = owner().elements==null
+                        ? new Forest.Many() /* FIXME */
+                        : ((Union)owner().elements[i]).epsilonForm(loc);
                 if (holder[i]==null) throw new Error("bad");
             }
-            return Sequence.this.postReduce(loc, holder, this);
+            return owner().postReduce(loc, holder, this);
         }
 
         public String   toString() {
@@ -272,7 +276,6 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
         return sb;
     }
 
-
     // Specialized Subclasses //////////////////////////////////////////////////////////////////////////////
 
     static class Singleton extends Sequence {
@@ -281,8 +284,9 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
         public Singleton(Element[] e, int idx) { super(e); this.idx = idx; }
         public <T> Forest<T> postReduce(Input.Region loc, Forest<T>[] args, Position p) { return args[idx]; }
         Sequence _clone() { return new Singleton(elements,idx); }
-        Forest epsilonForm(Input.Region loc, Grammar cache) {
-            return ((Union)elements[idx]).epsilonForm(loc, cache);
+        Forest epsilonForm(Input.Region loc) {
+            if (elements==null) return new Forest.Many(); /* FIXME */
+            return ((Union)elements[idx]).epsilonForm(loc);
         }
     }
 
@@ -321,7 +325,7 @@ public abstract class Sequence implements Iterable<Element>, SequenceOrElement {
             if (spacing) for(int i=0; i<50-len; i++) sb.append(' ');
             return sb;
         }
-        Forest epsilonForm(Input.Region loc, Grammar cache) {
+        Forest epsilonForm(Input.Region loc) {
             return Forest.create(loc, tag, new Forest[0], lifts);
         }
     }