added more flexible handling of Repeats -- now you can specify what they get tagged...
[sbp.git] / src / edu / berkeley / sbp / misc / MetaGrammar.java
index 33b3b11..c96d2ff 100644 (file)
@@ -115,14 +115,14 @@ public class MetaGrammar extends StringWalker {
         if      ("\\n".equals(head)) return new Character('\n');
         else if ("\\r".equals(head)) return new Character('\r');
         else if ("grammar".equals(head)) { for(Tree<String> t : tree.children()) walk(t); return this; }
-        else if ("*".equals(head))   return Repeat.many0((Element)walk(tree.child(0)));
-        else if ("+".equals(head))   return Repeat.many1((Element)walk(tree.child(0)));
-        else if ("+/".equals(head))  return Repeat.many1((Element)walk(tree.child(0)), (Element)walk(tree.child(1)));
-        else if ("*/".equals(head))  return Repeat.many0((Element)walk(tree.child(0)), (Element)walk(tree.child(1)));
-        else if ("++/".equals(head)) return Repeat.maximal1((Element)walk(tree.child(0)), (Element)walk(tree.child(1)));
-        else if ("**".equals(head))  return Repeat.maximal0((Element)walk(tree.child(0)));
-        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))   return Repeat.many0((Element)walk(tree.child(0)), repeatTag());
+        else if ("+".equals(head))   return Repeat.many1((Element)walk(tree.child(0)), repeatTag());
+        else if ("+/".equals(head))  return Repeat.many1((Element)walk(tree.child(0)), (Element)walk(tree.child(1)), repeatTag());
+        else if ("*/".equals(head))  return Repeat.many0((Element)walk(tree.child(0)), (Element)walk(tree.child(1)), repeatTag());
+        else if ("++/".equals(head)) return Repeat.maximal1((Element)walk(tree.child(0)), (Element)walk(tree.child(1)), repeatTag());
+        else if ("**".equals(head))  return Repeat.maximal0((Element)walk(tree.child(0)), repeatTag());
+        else if ("++".equals(head))  return Repeat.maximal1((Element)walk(tree.child(0)), repeatTag());
+        else if ("?".equals(head))   return Repeat.maybe((Element)walk(tree.child(0)), repeatTag());
         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(sequence(walk(tree, 1), true));
         else if ("and".equals(head)) return ((Sequence)walk(tree,0)).and(sequence(walk(tree, 1), true));
@@ -186,6 +186,7 @@ public class MetaGrammar extends StringWalker {
     }
 
     public Object convertLabel(String label) { return label; }
+    public Object repeatTag() { return null; }
 
     public Object walk(String tag, Object[] argo) {
         if (argo.length==0) return super.walk(tag, argo);
@@ -276,6 +277,7 @@ public class MetaGrammar extends StringWalker {
                 for(int i=0; i<o.length; i++) {
                     Object oi = o[i];
                     if (oi instanceof Keep)    {
+                        if (!unwrap && tag==null) throw new Error("cannot have labels in an untagged sequence: " + ((Keep)oi).label);
                         if (!keeping) { for(int k=0; k<i; k++) drops[k]=true; }
                         drops[i] = false;
                         keeping = true;
@@ -298,7 +300,7 @@ public class MetaGrammar extends StringWalker {
             Element[] expansion = o2;
             Sequence ret = null;
             if (dropAll || lame) ret = Sequence.drop(expansion, lame);
-            else if (unwrap)    ret = new Sequence.Unwrap(expansion, drops);
+            else if (unwrap)    ret = new Sequence.Unwrap(expansion, repeatTag(), drops);
             else if (keeping || tag!=null) ret = Sequence.rewritingSequence(tag, expansion, labels, drops);
             else {
                 int idx = -1;