allow lifts on any position
[sbp.git] / src / edu / berkeley / sbp / meta / GrammarAST.java
index 997d0b6..19f12a3 100644 (file)
@@ -79,26 +79,24 @@ public class GrammarAST {
         if (head.equals("Word")) return stringifyChildren(t);
         if (head.equals("Elements")) return seq2((ElementNode[])Reflection.rebuild(walkChildren(t), ElementNode[].class));
         if (head.equals("NonTerminalReference")) return new ReferenceNode(stringifyChildren(t.child(0)));
-        //if (head.equals(")")) return new ReferenceNode(stringifyChildren(t.child(0)));
-        if (head.equals("{")) return new XTree((Seq)walk(t.child(0)));
-        if (head.equals("::")) return tag((String)walk(t.child(0)), (Seq)walk(t.child(1)));
-        if (head.equals("++")) return plusmax((ElementNode)walk(t.child(0)));
-        if (head.equals("...")) return star(new TildeNode(new AtomNode()));
-        if (head.equals("+")) return plus((ElementNode)walk(t.child(0)));
-        if (head.equals("++/")) return plusmaxfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1)));
-        if (head.equals("+/")) return plusfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1)));
-        if (head.equals("**")) return starmax((ElementNode)walk(t.child(0)));
-        if (head.equals("*")) return star((ElementNode)walk(t.child(0)));
-        if (head.equals("**/")) return starmaxfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1)));
-        if (head.equals("*/")) return starfollow((ElementNode)walk(t.child(0)), (ElementNode)walk(t.child(1)));
-        if (head.equals("?")) return question((ElementNode)walk(t.child(0)));
-        if (head.equals("!")) return new DropNode((ElementNode)walk(t.child(0)));
-        if (head.equals("^")) return new LiteralNode((String)walk(t.child(0)), true);
-        if (head.equals("`")) {
-            ElementNode ret = (ElementNode)walk(t.child(0));
-            ret.lifted = true;
-            return ret;
-        }
+        if (head.equals(")"))   return new ReferenceNode(stringifyChildren(t.child(0)), true);
+        if (head.equals("{"))   return new BracedNode(walkSeq(t.child(0)));
+        if (head.equals("::"))  return walkSeq(t.child(1)).tag(walkString(t.child(0)));
+        if (head.equals("...")) return new DropNode(new RepeatNode(new TildeNode(new AtomNode()), null, true,  true,  false));
+
+        if (head.equals("++"))  return new RepeatNode(walkElement(t.child(0)), null,                      false, true,  true);
+        if (head.equals("+"))   return new RepeatNode(walkElement(t.child(0)), null,                      false, true,  false);
+        if (head.equals("++/")) return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)),   false, true,  true);
+        if (head.equals("+/"))  return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)),   false, true,  false);
+        if (head.equals("**"))  return new RepeatNode(walkElement(t.child(0)), null,                      true,  true,  true);
+        if (head.equals("*"))   return new RepeatNode(walkElement(t.child(0)), null,                      true,  true,  false);
+        if (head.equals("**/")) return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)),   true,  true,  true);
+        if (head.equals("*/"))  return new RepeatNode(walkElement(t.child(0)), walkElement(t.child(1)),   true,  true,  false);
+        if (head.equals("?"))   return new RepeatNode(walkElement(t.child(0)), null,                      true,  false, false);
+
+        if (head.equals("!"))   return new DropNode(walkElement(t.child(0)));
+        if (head.equals("^"))   return new LiteralNode(walkString(t.child(0)), true);
+        if (head.equals("`"))   return walkElement(t.child(0)).lifted();
         if (head.equals("Quoted")) return stringifyChildren(t);
         if (head.equals("Literal")) return new LiteralNode(walkString(t.child(0)));
         if (head.equals("->")) return walkSeq(t.child(0)).follow(walkElement(t.child(1)));
@@ -198,7 +196,7 @@ public class GrammarAST {
         public Union build(String rootNonterminal) {
             Context cx = new Context(this);
             Union u = null;
-            for(GrammarBuilder.NonTerminalNode nt : values())
+            for(GrammarAST.NonTerminalNode nt : values())
                 if (nt.name.equals(rootNonterminal))
                     return (Union)cx.get(nt.name);
             return null;
@@ -347,20 +345,20 @@ public class GrammarAST {
                     els[i] = elements[i].build(cx, cnt, dropall);
             }
             if (tag==null && multiNonDrop)
-                throw new RuntimeException("multiple non-dropped elements in sequence: " + Sequence.create(els, ""));
-            boolean lift = false;
-            if (elements.length > 0 && elements[0].lifted)
-                lift = true;
+                throw new RuntimeException("multiple non-dropped elements in sequence: " + Sequence.create("", els));
+            boolean[] lifts = new boolean[elements.length];
+            for(int i=0; i<elements.length; i++)
+                lifts[i] = elements[i].lifted;
             if (!multiNonDrop) {
                 if (idx == -1) 
                     ret = tag==null
-                        ? Sequence.create(els, illegalTag)
-                        : Sequence.createLeft(tag, els, drops, lift);
+                        ? Sequence.create(illegalTag, els)
+                        : Sequence.create(tag, els, drops, lifts);
                 else if (tag==null) ret = Sequence.create(els, idx);
-                else ret = Sequence.createLeft(tag, els, drops, lift);
+                else ret = Sequence.create(tag, els, drops, lifts);
             }
             if (multiNonDrop)
-                ret = Sequence.createLeft(tag, els, drops, lift);
+                ret = Sequence.create(tag, els, drops, lifts);
             if (this.follow != null)
                 ret = ret.followedBy(this.follow.toAtom(cx));
             return ret;