checkpoint
[sbp.git] / src / edu / berkeley / sbp / misc / MetaGrammar.java
index 259c77e..b4ffc00 100644 (file)
@@ -7,6 +7,8 @@ import java.io.*;
 
 public class MetaGrammar extends StringWalker {
 
+    boolean forceDrop = false;
+
     public static class Hack<T extends Input> extends Atom<T> {
         private final Atom<T> a;
         static final Topology leftright = CharRange.rightBrace.union(CharRange.leftBrace);
@@ -65,10 +67,10 @@ public class MetaGrammar extends StringWalker {
 
     public Union       getNonTerminal(String str) { return nonTerminal(str, null, false, false); }
     private Union       nonTerminal(String str) { return nonTerminal(str, null, false, false); }
-    public Union       anonymousNonTerminal(PreSequence[][] s) {
+    public Union       anonymousNonTerminal(Sequence[][] s) {
         return nonTerminal("anon"+(anon++), s, false, false);
     }
-    private Union       nonTerminal(String str, PreSequence[][] s, boolean synthetic, boolean dropAll) {
+    private Union       nonTerminal(String str, Sequence[][] s, boolean synthetic, boolean dropAll) {
         Union n = str.equals(startSymbol) ? g : nt.get(str);
         if (n == null) nt.put(str, n = new Union(str, synthetic));
         if (dropAll) this.dropAll.add(n);
@@ -77,14 +79,16 @@ public class MetaGrammar extends StringWalker {
         for(int i=0; i<s.length; i++) {
             if (s[i]==null) continue;
             HashSet<Sequence> temp = new HashSet<Sequence>();
-            for(PreSequence pre : s[i]) {
-                pre.not.addAll(seqs);
-                Sequence seq = pre.buildSequence(n, false, dropAll);
-                temp.add(seq);
-                n.add(seq);
+            for(Sequence pre : s[i]) {
+                for(Sequence sn : seqs) pre = pre.not(sn);
+                temp.add(pre);
+                n.add(pre);
             }
             seqs.addAll(temp);
         }
+        //StringBuffer sb = new StringBuffer();
+        //n.toString(sb);
+        //System.out.println(sb);
         return n;
     }
 
@@ -121,11 +125,19 @@ public class MetaGrammar extends StringWalker {
         else if ("epsilon".equals(head)) return Union.epsilon;
         else if ("()".equals(head)) return Union.epsilon;
         else if (")".equals(head)) return SELF;
-        else if ("psx".equals(head)) return walk(tree, 0);
+        else if ("psx".equals(head)) return ((PreSequence)walk(tree, 0)).buildSequence();
         else if ("nonTerminal".equals(head)) return getNonTerminal(string(tree.child(0)));
-        else if ("::=".equals(head)) return nonTerminal(string(tree.child(0)), (PreSequence[][])walk(tree, 1), false, false);
-        else if ("!::=".equals(head)) return nonTerminal(string(tree.child(0)), (PreSequence[][])walk(tree, 1), false, true);
-        else if ("(".equals(head)) return buildUnion((PreSequence[][])walk(tree, 0));
+        else if ("::=".equals(head)) {
+            forceDrop = false;
+            return nonTerminal(string(tree.child(0)), (Sequence[][])walk(tree, 1), false, false);
+        }
+        else if ("!::=".equals(head)) {
+            forceDrop = true;
+            Object ret = nonTerminal(string(tree.child(0)), (Sequence[][])walk(tree, 1), false, true);
+            forceDrop = false;
+            return ret;
+        }
+        else if ("(".equals(head)) return buildUnion((Sequence[][])walk(tree, 0));
         else if ("literal".equals(head)) { Element ret = string(string(tree.child(0))); dropAll.add(ret); return ret; }
         else if ("-".equals(head)) return new Range(walk(tree, 0).toString().charAt(0), walk(tree,1).toString().charAt(0));
         else if ("range".equals(head)) return new Range(walk(tree, 0).toString().charAt(0), walk(tree,0).toString().charAt(0));
@@ -178,7 +190,7 @@ public class MetaGrammar extends StringWalker {
         return super.walk(tag, argo);
     }
 
-    public Union buildUnion(PreSequence[][] p) {
+    public Union buildUnion(Sequence[][] p) {
         return anonymousNonTerminal(p);
     }
 
@@ -237,10 +249,13 @@ public class MetaGrammar extends StringWalker {
         }
         public Union    buildUnion() { return buildUnion("???"); }
         public boolean unwrap = false;
+        public Sequence buildSequence() { return buildSequence(null, false, forceDrop); }
         public Sequence buildSequence(Union u) { return buildSequence(u, false, false); }
         public Sequence buildSequence(Union u, boolean lame, boolean dropAll) {
-            for(Sequence s : and) u.add(s);
-            for(Sequence s : not) u.add(s);
+            if (u!=null) {
+                for(Sequence s : and) u.add(s);
+                for(Sequence s : not) u.add(s);
+            }
             HashSet<Sequence> set = new HashSet<Sequence>();
             Element[] o2 = o==null ? new Element[0] : new Element[o.length];
             int nonDrop = 0;