MAJOR: huge revamp of Sequence, Result, Reduction, Parser, Node, GSS
[sbp.git] / src / edu / berkeley / sbp / meta / MetaGrammarBindings.java
index 41e343b..927cd62 100644 (file)
@@ -1,3 +1,5 @@
+// Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
+
 package edu.berkeley.sbp.meta;
 import edu.berkeley.sbp.util.*;
 import edu.berkeley.sbp.*;
@@ -77,14 +79,13 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
                 Seq[] group = sequences[i];
                 Union u2 = new Union(null, false);
                 if (sequences.length==1) u2 = u;
-                for(int j=0; j<group.length; j++) {
+                for(int j=0; j<group.length; j++)
                     group[j].build(cx, u2, cnt);
-                }
                 if (sequences.length==1) break;
-                Sequence seq = Sequence.singleton(u2);
-                for(Sequence s : bad2) seq = seq.not(s);
+                Sequence seq = Sequence.create(u2);
+                for(Sequence s : bad2) seq = seq.andnot(s);
                 u.add(seq);
-                bad2.add(Sequence.singleton(u2));
+                bad2.add(Sequence.create(u2));
             }
         }
     }
@@ -128,11 +129,11 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
             HashSet<Sequence> bad2 = new HashSet<Sequence>();
 
             Union urep = new Union(null, false);
-            urep.add(Sequence.empty);
+            urep.add(Sequence.create());
             if (sep != null)
-                urep.add(Sequence.singleton(new Element[] { cx.get(sep), u }, 1));
+                urep.add(Sequence.create(new Element[] { cx.get(sep), u }, 1));
             else
-                urep.add(Sequence.singleton(new Element[] { u }, 0));
+                urep.add(Sequence.create(new Element[] { u }, 0));
 
             for(int i=0; i<sequences.length; i++) {
                 Seq[] group = sequences[i];
@@ -141,16 +142,17 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
                 for(int j=0; j<group.length; j++) {
                     Union u3 = new Union(null, false);
                     group[j].build(cx, u3, this);
-                    Sequence s = Sequence.unwrap(new Element[] { u3, urep },
-                                                 cx.rm.repeatTag(),
-                                                 new boolean[] { false, false });
+                    Sequence s = Sequence.create(cx.rm.repeatTag(),
+                                                 new Element[] { u3, urep },
+                                                 new boolean[] { false, false },
+                                                 true);
                     u2.add(s);
                 }
                 if (sequences.length==1) break;
-                Sequence seq = Sequence.singleton(u2);
-                for(Sequence s : bad2) seq = seq.not(s);
+                Sequence seq = Sequence.create(u2);
+                for(Sequence s : bad2) seq = seq.andnot(s);
                 u.add(seq);
-                bad2.add(Sequence.singleton(u2));
+                bad2.add(Sequence.create(u2));
             }
         }
     }
@@ -193,7 +195,7 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         public Seq(ElementNode e) { this(new ElementNode[] { e }); }
         public Seq(ElementNode[] elements) { this.elements = elements; }
         public Atom toAtom(Context cx) {
-            if (elements.length != 1) throw new Error("FIXME");
+            if (elements.length != 1) throw new Error("you attempted to use ->, **, ++, or a similar character-class operator on a [potentially] multicharacter production");
             return elements[0].toAtom(cx);
         }
         public Seq tag(String tag) { this.tag = prefix+tag; return this; }
@@ -223,14 +225,12 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         }
         public Sequence build(Context cx, Union u, NonTerminalNode cnt) {
             Sequence ret = build0(cx, cnt);
-            for(Seq s : and) { Sequence dork = s.build(cx, u, cnt); ret = ret.and(dork); }
-            for(Seq s : not) { Sequence dork = s.build(cx, u, cnt); ret = ret.not(dork); }
-            u.add(ret);
+            for(Seq s : and) { Sequence dork = s.build(cx, null, cnt); ret = ret.and(dork); }
+            for(Seq s : not) { Sequence dork = s.build(cx, null, cnt); ret = ret.andnot(dork); }
+            if (u!=null) u.add(ret);
             return ret;
         }
         public Sequence build0(Context cx, NonTerminalNode cnt) {
-            boolean dropAll = false;
-            if (tag!=null && tag.endsWith("()")) dropAll = true;
             boolean[] drops = new boolean[elements.length];
             Element[] els = new Element[elements.length];
             for(int i=0; i<elements.length; i++) {
@@ -240,19 +240,16 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
                     tag = elements[i].getOwnerTag();
             }
             Sequence ret = null;
-            if (dropAll)     ret = Sequence.drop(els);
-            else {
-                Production prod = new Production(tag, (cnt==null?null:cnt.name), els, drops);
-                ret = cx.rm.createSequence(prod);
-                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));
-                    if (idx != -1) ret = Sequence.singleton(els, idx);
-                    else           ret = Sequence.drop(els);
-                }
+            Production prod = new Production(tag, (cnt==null?null:cnt.name), els, drops);
+            ret = cx.rm.createSequence(prod);
+            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.create(els, null));
+                if (idx != -1) ret = Sequence.create(els, idx);
+                else           ret = Sequence.create(els, null);
             }
             if (this.follow != null)
                 ret = ret.followedBy(this.follow.toAtom(cx));
@@ -273,7 +270,7 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
     public static @bind.as("()")  ElementNode   epsilon()                         { return new Constant(epsilon); }
 
     private static Union epsilon = new Union("()");
-    static { epsilon.add(Sequence.empty); }
+    static { epsilon.add(Sequence.create()); }
 
     public static class NonTerminalReferenceNode extends ElementNode {
         public String nonTerminal;
@@ -324,13 +321,18 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         }
     }
 
+    public static @bind.as("\\{") ElementNode   leftBrace() {
+        return new Drop(new CharClass(new Range[] { new Range(CharAtom.left, CharAtom.left) })); }
+    public static @bind.as("\\}") ElementNode   rightBrace() {
+        return new Drop(new CharClass(new Range[] { new Range(CharAtom.right, CharAtom.right) })); }
+
     public static @bind.as("{")           class XTree                 extends ElementNode {
         public @bind.arg Seq body;
         public Element build(Context cx, NonTerminalNode cnt) {
             Union u = new Union(null, false);
             Sequence s = body.build(cx, u, null);
             Union u2 = new Union(null, false);
-            u2.add(Sequence.singleton(new Element[] {
+            u2.add(Sequence.create(new Element[] {
                 CharAtom.leftBrace,
                 cx.get("ws"),
                 u,
@@ -352,10 +354,10 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         }
         public Element build(Context cx, NonTerminalNode cnt) {
             return (!max)
-                ? Sequence.repeat(e.build(cx, null), zero, many, sep==null ? null : sep.build(cx, null), cx.rm.repeatTag())
+                ? Repeat.repeat(e.build(cx, null), zero, many, sep==null ? null : sep.build(cx, null), cx.rm.repeatTag())
                 : sep==null
-                ? Sequence.repeatMaximal(e.toAtom(cx), zero, many, cx.rm.repeatTag())
-                : Sequence.repeatMaximal(e.build(cx, null), zero, many, sep.toAtom(cx), cx.rm.repeatTag());
+                ? Repeat.repeatMaximal(e.toAtom(cx), zero, many, cx.rm.repeatTag())
+                : Repeat.repeatMaximal(e.build(cx, null), zero, many, sep.toAtom(cx), cx.rm.repeatTag());
         }
     }
 
@@ -392,15 +394,19 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
     public static @bind.as("~")   ElementNode tilde(final ElementNode e) {
         return new ElementNodeWrapper(e) {
                 public Atom toAtom(Context cx) {
-                    return infer((Topology<Character>)e.toAtom(cx).complement().minus(CharAtom.braces));
+                    return infer((Topology<Character>)e.toAtom(cx).complement()/*.minus(CharAtom.braces)*/);
                 }
                 public Element build(Context cx, NonTerminalNode cnt) {
-                    return infer((Topology<Character>)e.toAtom(cx).complement().minus(CharAtom.braces));
+                    return infer((Topology<Character>)e.toAtom(cx).complement()/*.minus(CharAtom.braces)*/);
                 } }; }
 
     public static @bind.as("Word")        String word(String s) { return s; }
     public static @bind.as("Quoted")      String quoted(String s) { return s; }
-    public static @bind.as("escaped")     String c(char c) { return c+""; }
+    public static @bind.as("escaped")     String c(char c) {
+        if (c=='{') return CharAtom.left+"";
+        if (c=='}') return CharAtom.right+"";
+        return c+"";
+    }
     public static @bind.as("EmptyString") String emptystring() { return ""; }
     public static @bind.as("\n")          String retur() { return "\n"; }
     public static @bind.as("\r")          String lf() { return "\r"; }