checkpoint
[sbp.git] / src / edu / berkeley / sbp / misc / MetaGrammar.java
index 03f8f97..b1a3e8c 100644 (file)
@@ -40,9 +40,9 @@ public class MetaGrammar extends StringWalker {
     private boolean strings;
 
     private Element  set(Range.Set r) { if (strings) throw new Error(); return CharRange.set(r); }
-    private Element  string(String s) { return strings ? StringToken.string(s) : CharRange.string(s); }
-    private Atom     leftBrace()      { return strings ? StringToken.leftBrace : CharRange.leftBrace; }
-    private Atom     rightBrace()     { return strings ? StringToken.rightBrace : CharRange.rightBrace; }
+    private Element  string(String s) { return strings ? StringInput.string(s) : CharRange.string(s); }
+    private Atom     leftBrace()      { return strings ? StringInput.leftBrace : CharRange.leftBrace; }
+    private Atom     rightBrace()     { return strings ? StringInput.rightBrace : CharRange.rightBrace; }
 
     public MetaGrammar() { this("s", false); }
     public MetaGrammar(String s) { this(s, false); }
@@ -63,8 +63,12 @@ public class MetaGrammar extends StringWalker {
 
     // MetaGrammar //////////////////////////////////////////////////////////////////////////////
 
-    public Union       nonTerminal(String str) { return nonTerminal(str, null, false, false); }
-    public Union       nonTerminal(String str, PreSequence[][] s, boolean synthetic, boolean dropAll) {
+    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) {
+        return nonTerminal("anon"+(anon++), s, false, false);
+    }
+    private Union       nonTerminal(String str, PreSequence[][] 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);
@@ -117,10 +121,10 @@ 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 ("nonTerminal".equals(head)) return nonTerminal(string(tree.child(0)), null, false, false);
+        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 nonTerminal("anon"+(anon++), (PreSequence[][])walk(tree, 0), false, false);
+        else if ("(".equals(head)) return buildUnion((PreSequence[][])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));
@@ -173,6 +177,10 @@ public class MetaGrammar extends StringWalker {
         return super.walk(tag, argo);
     }
 
+    public Union buildUnion(PreSequence[][] p) {
+        return anonymousNonTerminal(p);
+    }
+
     //////////////////////////////////////////////////////////////////////////////
 
     public class PreSequence {
@@ -221,11 +229,12 @@ public class MetaGrammar extends StringWalker {
             this.drops = drops==null ? new boolean[o.length] : drops;
         }
 
-        public Union    buildUnion() {
-            Union u = new Union("???");
+        public Union    buildUnion(String s) {
+            Union u = new Union(s);
             u.add(buildSequence(u));
             return u;
         }
+        public Union    buildUnion() { return buildUnion("???"); }
         public boolean unwrap = false;
         public Sequence buildSequence(Union u) { return buildSequence(u, false, false); }
         public Sequence buildSequence(Union u, boolean lame, boolean dropAll) {
@@ -249,7 +258,11 @@ public class MetaGrammar extends StringWalker {
             }
             Element[] expansion = o2;
             Sequence ret = null;
-            if (dropAll || lame) ret = Sequence.drop(expansion, and, not, lame);
+            if (dropAll || lame) {
+                ret = Sequence.drop(expansion, lame);
+                for(Sequence s : and) ret = ret.and(s);
+                for(Sequence s : not) ret = ret.not(s);
+            }
             else if (unwrap)    ret = new Sequence.Unwrap(expansion, drops, and, not);
             else if (tag!=null) ret = Sequence.rewritingSequence(tag, expansion, drops, and, not);
             else {
@@ -257,9 +270,13 @@ public class MetaGrammar extends StringWalker {
                 for(int i=0; i<expansion.length; i++)
                     if (!drops[i])
                         if (idx==-1) idx = i;
-                        else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(expansion,null,null,false));
+                        else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(expansion,false));
                 if (idx != -1) ret = Sequence.singleton(expansion, idx, and, not);
-                else           ret = Sequence.drop(expansion, and, not, false);
+                else           {
+                    ret = Sequence.drop(expansion, false);
+                    for(Sequence s : and) ret = ret.and(s);
+                    for(Sequence s : not) ret = ret.not(s);
+                }
             }
             set.add(ret);
             if (this.noFollow != null) ret.noFollow = new Atom.Invert(new Atom.Infer(this.noFollow));