checkpoint
[sbp.git] / src / edu / berkeley / sbp / misc / MetaGrammar.java
index 3a55383..7fe8afa 100644 (file)
@@ -7,8 +7,6 @@ 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);
@@ -104,6 +102,9 @@ public class MetaGrammar extends StringWalker {
         return ret;
     }
 
+    public Sequence sequence(Object o, boolean lame) {
+        return new PreSequence((Element[])Reflection.lub((Object[])o), null).buildSequence(null, lame, false);
+    }
     public Object walk(Tree<String> tree) {
         String head = tree.head();
         if (tree.numChildren()==0) return super.walk(tree);
@@ -119,41 +120,25 @@ public class MetaGrammar extends StringWalker {
         else if ("++".equals(head))  return Repeat.maximal1((Element)walk(tree.child(0)));
         else if ("?".equals(head))   return Repeat.maybe((Element)walk(tree.child(0)));
         else if ("!".equals(head))   { Element e = (Element)walk(tree.child(0)); dropAll.add(e); return e; }
-        else if ("&".equals(head))
-            return ((Sequence)walk(tree,0)).and(new PreSequence((Element[])Reflection.lub((Object[])walk(tree, 1)), null).buildSequence(null, true, false));
-        else if ("&~".equals(head))
-            return ((Sequence)walk(tree,0)).not(new PreSequence((Element[])Reflection.lub((Object[])walk(tree, 1)), null).buildSequence(null, true, false));
+        else if ("&".equals(head))   return ((Sequence)walk(tree,0)).and(sequence(walk(tree, 1), true));
+        else if ("&~".equals(head))  return ((Sequence)walk(tree,0)).not(sequence(walk(tree, 1), true));
         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 ((PreSequence)walk(tree, 0)).buildSequence();
         else if ("nonTerminal".equals(head)) return getNonTerminal(string(tree.child(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 nonTerminal(string(tree.child(0)), (Sequence[][])walk(tree, 1), false, false);
         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));
         else if ("gram".equals(head)) return walk(tree, 0);
-        else if ("=>".equals(head)) {
-            PreSequence p = (PreSequence)walk(tree, 0);
-            p.tag = string(tree.child(1));
-            return p.buildSequence(null, false, "()".equals(p.tag));
-        }
+        else if ("=>".equals(head)) return ((PreSequence)walk(tree, 0)).buildSequence(null, false, string(tree.child(1)));
         else if ("[]".equals(head)) { PreSequence p = (PreSequence)walk(tree, 0); p.unwrap = true; return p; }
         else if ("psy".equals(head)) return (PreSequence)walk(tree, 0);
         else if ("->".equals(head)) { PreSequence p = (PreSequence)walk(tree, 0); p.noFollow = (Element)walk(tree, 1); return p; }
         else if ("/".equals(head)) return ((PreSequence)walk(tree, 0)).sparse((Element)walk(tree, 1));
-        else if ("~".equals(head))
-            return new Hack(new Atom.Invert(new Atom.Infer((Element)walk(tree, 0))));
+        else if ("~".equals(head)) return new Hack(new Atom.Invert(new Atom.Infer((Element)walk(tree, 0))));
         else if ("ps".equals(head)) return new PreSequence((Element[])walk(tree, 0));
         else if ("qprod".equals(head)) {
             String s = string(tree.child(0));
@@ -246,8 +231,12 @@ 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() { return buildSequence(null, false, false); }
         public Sequence buildSequence(Union u) { return buildSequence(u, false, false); }
+        public Sequence buildSequence(Union u, boolean lame, String tag) {
+            this.tag = tag;
+            return buildSequence(u, lame, "()".equals(tag));
+        }
         public Sequence buildSequence(Union u, boolean lame, boolean dropAll) {
             if (u!=null) {
                 for(Sequence s : and) u.add(s);