checkpoint
[sbp.git] / src / edu / berkeley / sbp / misc / MetaGrammar.java
index 73c6fdd..e9c4413 100644 (file)
@@ -50,6 +50,10 @@ public class MetaGrammar extends StringWalker {
 
     public static class Meta {
         public Object repeatTag() { return null; }
+        public Sequence tryResolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) {
+            //return resolveTag(s, nonTerminalName, els, labels, drops);
+            return null;
+        }
         public Sequence resolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) {
             return Sequence.rewritingSequence(s, els, labels, drops);
         }
@@ -195,6 +199,9 @@ public class MetaGrammar extends StringWalker {
                 boolean dropAll = false;
                 if (tag!=null && tag.equals("[]")) unwrap = true;
                 if (tag!=null && "()".equals(tag)) dropAll=true;
+
+                NonTerminal old = bc.currentNonTerminal;
+                bc.currentNonTerminal = null;
                 for(int i=0; i<elements.length; i++) {
                     int j = separator==null ? i : i*2;
                     els[j] = elements[i].build(bc);
@@ -205,6 +212,8 @@ public class MetaGrammar extends StringWalker {
                         drops[j+1] = true;
                     }
                 }
+                bc.currentNonTerminal = old;
+
                 Sequence ret = null;
                 if (dropAll)     ret = Sequence.drop(els, false);
                 else if (unwrap) ret = Sequence.unwrap(els, repeatTag(), drops);
@@ -212,13 +221,16 @@ public class MetaGrammar extends StringWalker {
                     ret = resolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops);
                     System.err.println("resolvetag " + tag + " => " + ret);
                 } else {
-                    int idx = -1;
-                    for(int i=0; i<els.length; i++)
-                        if (!drops[i])
-                            if (idx==-1) idx = i;
-                            else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els,false));
-                    if (idx != -1) ret = Sequence.singleton(els, idx);
-                    else           ret = Sequence.drop(els, false);
+                    ret = tryResolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops);
+                    if (ret==null) {
+                        int idx = -1;
+                        for(int i=0; i<els.length; i++)
+                            if (!drops[i])
+                                if (idx==-1) idx = i;
+                                else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els,false));
+                        if (idx != -1) ret = Sequence.singleton(els, idx);
+                        else           ret = Sequence.drop(els, false);
+                    }
                 }
                 if (this.followedBy != null)
                     ret.follow = infer(this.followedBy.build(bc));
@@ -266,7 +278,7 @@ public class MetaGrammar extends StringWalker {
                 //System.err.println("MetaClause.makeMetaClause("+t+")");
                 if (t==null) return new Epsilon();
                 if (t.head()==null) return new Epsilon();
-                if (t.head().equals("{")) throw new Error("metatree: " + t);
+                if (t.head().equals("{")) return new MetaTree(makeConjunct(t.child(0)));
                 if (t.head().equals("*")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, true, true);
                 if (t.head().equals("+")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, false, true);
                 if (t.head().equals("?")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, true, false);
@@ -337,16 +349,27 @@ public class MetaGrammar extends StringWalker {
                 public String toString() { return "( " + body + " )"; }
                 public Element build(BuildContext bc) { return body.buildAnon(bc); }
             }
-            /*
-            public static class MetaTree extends MetaClause {
+
+            public class MetaTree extends MetaClause {
                 public Conjunct body;
-                public MetaTree(Tree<String> t) { this.body = makeConjunct(t); }
+                public MetaTree(Conjunct c) { this.body = c; }
                 public String toString() { return "{ " + body + " }"; }
                 public Element build(BuildContext bc) {
-                    return new Union("{}");// body.buildSequence();
+                    Union u = new Union();
+                    Union u2 = new Union();
+                    Sequence seq = body.buildSequence(bc);
+                    u2.add(seq);
+                    u.add(Sequence.singleton(new Element[] { CharRange.leftBrace,
+                                                             new NonTerminalReference("ws").build(bc),
+                                                             u2,
+                                                             new NonTerminalReference("ws").build(bc),
+                                                             CharRange.rightBrace }
+                                             , 2));
+                    //u.add(seq);
+                    return u;
                 }
             }
-            */
+
             public class MetaRange extends MetaClause {
                 Range.Set range = new Range.Set();
                 public String toString() { return range.toString(); }
@@ -371,6 +394,7 @@ public class MetaGrammar extends StringWalker {
             public class NonTerminalReference extends MetaClause {
                 public String name;
                 public NonTerminalReference(Tree<String> name) { this.name = string(name); }
+                public NonTerminalReference(String name) { this.name = name; }
                 public Element build(BuildContext bc) { return bc.build(name); }
                 public String toString() { return name; } 
             }