checkpoint
[sbp.git] / src / edu / berkeley / sbp / meta / MetaGrammarBindings.java
index 37635a5..dc35dfc 100644 (file)
@@ -21,11 +21,22 @@ public class MetaGrammarBindings {
             for(NonTerminalNode nt : values()) ret += nt + ", ";
             return ret + " ]";
         }
+        public Union build(String s, GrammarBindingResolver rm) {
+            Context cx = new Context(this,rm);
+            Union u = null;
+            for(MetaGrammarBindings.NonTerminalNode nt : values()) {
+                Union el = (Union)cx.get(nt.name);
+                StringBuffer st = new StringBuffer();
+                el.toString(st);
+                if (nt.name.equals(s)) u = el;
+            }
+            return u;
+        }
     }
 
     public abstract static class UnionNode extends ElementNode {
         public Seq[][] sequences;
-        public void build(MetaGrammar.Context cx, Union u) {
+        public void build(Context cx, Union u) {
             HashSet<Sequence> bad2 = new HashSet<Sequence>();
             for(int i=0; i<sequences.length; i++) {
                 Seq[] group = sequences[i];
@@ -58,8 +69,8 @@ public class MetaGrammarBindings {
             this.rep = rep;
             this.sep = sep;
         }
-        public Element build(MetaGrammar.Context cx) { return cx.get(name); }
-        public void build(MetaGrammar.Context cx, Union u) {
+        public Element build(Context cx) { return cx.get(name); }
+        public void build(Context cx, Union u) {
             if (!rep) { super.build(cx, u); return; }
             HashSet<Sequence> bad2 = new HashSet<Sequence>();
 
@@ -99,7 +110,7 @@ public class MetaGrammarBindings {
         public @bind.as("(") AnonUnionNode(Seq[][] sequences) {
             this.sequences = sequences;
         }
-        public Element build(MetaGrammar.Context cx) {
+        public Element build(Context cx) {
             Union ret = new Union();
             build(cx, ret);
             return ret;
@@ -112,28 +123,32 @@ public class MetaGrammarBindings {
         public char first;
         public char last;
     }
+
     public static abstract class ElementNode {
         public String getLabel() { return null; }
         public String getOwnerTag() { return null; }
         public boolean drop() { return false; }
-        public abstract Element build(MetaGrammar.Context cx);
+        public abstract Element build(Context cx);
     }
+
     public static class Drop extends ElementNode {
         public ElementNode e;
         public Drop(ElementNode e) { this.e = e; }
         public String getLabel() { return null; }
         public boolean drop() { return true; }
         public String getOwnerTag() { return e.getOwnerTag(); }
-        public Element build(MetaGrammar.Context cx) { return e.build(cx); }
+        public Element build(Context cx) { return e.build(cx); }
     }
+
     public static class Label extends ElementNode {
         public String label;
         public ElementNode e;
         public Label(String label, ElementNode e) { this.e = e; this.label = label; }
         public String getLabel() { return label; }
         public String getOwnerTag() { return e.getOwnerTag(); }
-        public Element build(MetaGrammar.Context cx) { return e.build(cx); }
+        public Element build(Context cx) { return e.build(cx); }
     }
+
     public static /*abstract*/ class Seq {
         HashSet<Seq> and = new HashSet<Seq>();
         HashSet<Seq> not = new HashSet<Seq>();
@@ -171,7 +186,7 @@ public class MetaGrammarBindings {
             this.elements = elements;
             return this;
         }
-        public Sequence build(MetaGrammar.Context cx, Union u, boolean lame) {
+        public Sequence build(Context cx, Union u, boolean lame) {
             Sequence ret = build0(cx, lame || this.lame);
             for(Seq s : and) { Sequence dork = s.build(cx, u, true); ret = ret.and(dork); }
             for(Seq s : not) { Sequence dork = s.build(cx, u, true); ret = ret.not(dork); }
@@ -179,7 +194,7 @@ public class MetaGrammarBindings {
             ret.lame = lame;
             return ret;
         }
-        public Sequence build0(MetaGrammar.Context cx, boolean lame) {
+        public Sequence build0(Context cx, boolean lame) {
             boolean dropAll = lame;
             if (tag!=null && "()".equals(tag)) dropAll = true;
             Object[] labels = new Object[elements.length];
@@ -227,7 +242,7 @@ public class MetaGrammarBindings {
 
     public static @bind.as("NonTerminalReference") class NonTerminalReferenceNode extends ElementNode {
         public @bind.arg String nonTerminal;
-        public Element build(MetaGrammar.Context cx) { return cx.get(nonTerminal); }
+        public Element build(Context cx) { return cx.get(nonTerminal); }
     }
 
     public static class Literal extends Constant {
@@ -238,7 +253,7 @@ public class MetaGrammarBindings {
     public static                     class CharClass            extends ElementNode {
         Range[] ranges;
         public @bind.as("[") CharClass(Range[] ranges) { this.ranges = ranges; }
-        public Element build(MetaGrammar.Context cx) {
+        public Element build(Context cx) {
             edu.berkeley.sbp.util.Range.Set set = new edu.berkeley.sbp.util.Range.Set();
             for(Range r : ranges)
                 set.add(r.first, r.last);
@@ -248,7 +263,7 @@ public class MetaGrammarBindings {
 
     public static @bind.as("{")           class XTree                 extends ElementNode {
         public @bind.arg Seq body;
-        public Element build(MetaGrammar.Context cx) {
+        public Element build(Context cx) {
             Union u = new Union();
             Sequence s = body.build(cx, u, false);
             Union u2 = new Union();
@@ -268,7 +283,7 @@ public class MetaGrammarBindings {
         public boolean zero, many, max;
         public Rep(ElementNode e, ElementNode sep, boolean zero, boolean many, boolean max) {
             this.e = e; this.sep = sep; this.zero = zero; this.many = many; this.max = max;}
-        public Element build(MetaGrammar.Context cx) {
+        public Element build(Context cx) {
             return (!max)
                 ? Sequence.repeat(e.build(cx),        zero, many, sep==null ? null : sep.build(cx), cx.rm.repeatTag())
                 : sep==null
@@ -279,12 +294,12 @@ public class MetaGrammarBindings {
     public static class Constant extends ElementNode {
         Element constant;
         public Constant(Element constant) { this.constant = constant; }
-        public Element build(MetaGrammar.Context cx) { return constant; }
+        public Element build(Context cx) { return constant; }
     }
     public abstract static class PostProcess extends ElementNode {
         ElementNode e;
         public PostProcess(ElementNode e) { this.e = e; }
-        public Element build(MetaGrammar.Context cx) { return postProcess(e.build(cx)); }
+        public Element build(Context cx) { return postProcess(e.build(cx)); }
         public abstract Element postProcess(Element e);
     }
 
@@ -313,10 +328,6 @@ public class MetaGrammarBindings {
                     return infer((Topology<Character>)Atom.toAtom(e).complement()); 
                 } }; }
 
-    public static @bind.as("^^")  void doublecaret(final ElementNode e)                 { throw new Error("not implemented"); }
-
-    //public static @bind.as("(")   ElementNode subexpression(Seq[][] rhs)                { return new NonTerminalNode(rhs); }
-
     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+""; }
@@ -326,4 +337,49 @@ public class MetaGrammarBindings {
 
     static Atom infer(Element e)  { return infer((Topology<Character>)Atom.toAtom(e)); }
     static Atom infer(Topology<Character> t) { return new CharRange(new CharTopology(t)); }
+
+    public static class Context {
+        public HashMap<String,Union> map = new HashMap<String,Union>();
+        public GrammarNode grammar;
+        public String cnt = null;
+        public GrammarBindingResolver rm;
+        public Context(GrammarNode g, GrammarBindingResolver rm) {
+            this.grammar = g;
+            this.rm = rm;
+        }
+        public Union build() {
+            Union ret = null;
+            for(NonTerminalNode nt : grammar.values()) {
+                Union u = get(nt.name);
+                if ("s".equals(nt.name))
+                    ret = u;
+            }
+            return ret;
+        }
+        public Context(Tree t, GrammarBindingResolver rm) {
+            this.rm = rm;
+            Tree.TreeFunctor<Object,Object> red = (Tree.TreeFunctor<Object,Object>)t.head();
+            this.grammar = (GrammarNode)red.invoke(t.children());
+        }
+        public Union peek(String name) { return map.get(name); }
+        public void  put(String name, Union u) { map.put(name, u); }
+        public Union get(String name) {
+            Union ret = map.get(name);
+            if (ret != null) return ret;
+            ret = new Union(name);
+            map.put(name, ret);
+            NonTerminalNode nt = grammar.get(name);
+            if (nt==null) {
+                System.err.println("*** warning could not find " + name);
+            } else {
+                String old = cnt;
+                cnt = name;
+                nt.build(this, ret);
+                cnt = old;
+            }
+            return ret;
+        }
+
+    }
+
 }