checkpoint
[sbp.git] / src / edu / berkeley / sbp / misc / MetaGrammar.java
index c8665fa..4348dec 100644 (file)
@@ -1,11 +1,21 @@
 package edu.berkeley.sbp.misc;
 import edu.berkeley.sbp.util.*;
 import edu.berkeley.sbp.*;
+import edu.berkeley.sbp.chr.*;
 import java.util.*;
 import java.io.*;
 
 public class MetaGrammar extends StringWalker {
 
+    public static class Hack<T extends Input> extends Atom<T> {
+        private final Atom<T> a;
+        static final Topology leftright = CharRange.rightBrace.union(CharRange.leftBrace);
+        public Hack(Atom<T> a) { this.a = a; }
+        public Topology<T> top() { return a.minus(leftright); }
+        public String toString() { return "~"+a; }
+    }
+
+
     public static Union make() throws Exception {
         return ((MetaGrammar)new MetaGrammar().walk(meta)).done();
     }
@@ -29,10 +39,10 @@ public class MetaGrammar extends StringWalker {
     private String startSymbol;
     private boolean strings;
 
-    private Element  set(Range.Set r) { if (strings) throw new Error(); return CharToken.set(r); }
-    private Element  string(String s) { return strings ? StringToken.string(s) : CharToken.string(s); }
-    private Atom     leftBrace()      { return strings ? StringToken.leftBrace : CharToken.leftBrace; }
-    private Atom     rightBrace()     { return strings ? StringToken.rightBrace : CharToken.rightBrace; }
+    private Element  set(Range.Set r) { if (strings) throw new Error(); return CharRange.set(r); }
+    private Element  string(String s) { return strings ? StringInput.string(s) : CharRange.string(s); }
+    private Atom     leftBrace()      { return strings ? StringInput.leftBrace : CharRange.leftBrace; }
+    private Atom     rightBrace()     { return strings ? StringInput.rightBrace : CharRange.rightBrace; }
 
     public MetaGrammar() { this("s", false); }
     public MetaGrammar(String s) { this(s, false); }
@@ -53,8 +63,12 @@ public class MetaGrammar extends StringWalker {
 
     // MetaGrammar //////////////////////////////////////////////////////////////////////////////
 
-    public Union       nonTerminal(String str) { return nonTerminal(str, null, false, false); }
-    public Union       nonTerminal(String str, PreSequence[][] s, boolean synthetic, boolean dropAll) {
+    public Union       getNonTerminal(String str) { return nonTerminal(str, null, false, false); }
+    private Union       nonTerminal(String str) { return nonTerminal(str, null, false, false); }
+    public Union       anonymousNonTerminal(PreSequence[][] s) {
+        return nonTerminal("anon"+(anon++), s, false, false);
+    }
+    private Union       nonTerminal(String str, PreSequence[][] s, boolean synthetic, boolean dropAll) {
         Union n = str.equals(startSymbol) ? g : nt.get(str);
         if (n == null) nt.put(str, n = new Union(str, synthetic));
         if (dropAll) this.dropAll.add(n);
@@ -107,10 +121,10 @@ public class MetaGrammar extends StringWalker {
         else if ("epsilon".equals(head)) return Union.epsilon;
         else if ("()".equals(head)) return Union.epsilon;
         else if (")".equals(head)) return SELF;
-        else if ("nonTerminal".equals(head)) return nonTerminal(string(tree.child(0)), null, false, false);
+        else if ("nonTerminal".equals(head)) return getNonTerminal(string(tree.child(0)));
         else if ("::=".equals(head)) return nonTerminal(string(tree.child(0)), (PreSequence[][])walk(tree, 1), false, false);
         else if ("!::=".equals(head)) return nonTerminal(string(tree.child(0)), (PreSequence[][])walk(tree, 1), false, true);
-        else if ("(".equals(head)) return nonTerminal("anon"+(anon++), (PreSequence[][])walk(tree, 0), false, false);
+        else if ("(".equals(head)) return buildUnion((PreSequence[][])walk(tree, 0));
         else if ("literal".equals(head)) { Element ret = string(string(tree.child(0))); dropAll.add(ret); return ret; }
         else if ("-".equals(head)) return new Range(walk(tree, 0).toString().charAt(0), walk(tree,1).toString().charAt(0));
         else if ("range".equals(head)) return new Range(walk(tree, 0).toString().charAt(0), walk(tree,0).toString().charAt(0));
@@ -123,7 +137,7 @@ public class MetaGrammar extends StringWalker {
         else if ("psylr".equals(head)) throw new Error("not supported");
         else if ("/".equals(head)) return ((PreSequence)walk(tree, 0)).sparse((Element)walk(tree, 1));
         else if ("~".equals(head))
-            return new Atom.Hack(new Atom.Invert(new Atom.Infer((Element)walk(tree, 0))));
+            return new Hack(new Atom.Invert(new Atom.Infer((Element)walk(tree, 0))));
         else if ("ps".equals(head)) return new PreSequence((Element[])walk(tree, 0));
         else if ("ps".equals(head)) return new PreSequence((Element[])walk(tree, 0));
         else if ("qprod".equals(head)) {
@@ -163,6 +177,10 @@ public class MetaGrammar extends StringWalker {
         return super.walk(tag, argo);
     }
 
+    public Union buildUnion(PreSequence[][] p) {
+        return anonymousNonTerminal(p);
+    }
+
     //////////////////////////////////////////////////////////////////////////////
 
     public class PreSequence {
@@ -211,11 +229,12 @@ public class MetaGrammar extends StringWalker {
             this.drops = drops==null ? new boolean[o.length] : drops;
         }
 
-        public Union    buildUnion() {
-            Union u = new Union("???");
+        public Union    buildUnion(String s) {
+            Union u = new Union(s);
             u.add(buildSequence(u));
             return u;
         }
+        public Union    buildUnion() { return buildUnion("???"); }
         public boolean unwrap = false;
         public Sequence buildSequence(Union u) { return buildSequence(u, false, false); }
         public Sequence buildSequence(Union u, boolean lame, boolean dropAll) {
@@ -278,7 +297,7 @@ public class MetaGrammar extends StringWalker {
         }
 
         out.append("\n        // DO NOT EDIT STUFF BELOW: IT IS AUTOMATICALLY GENERATED\n");
-        new CharToStringParser(MetaGrammar.make()).parse(new FileInputStream(args[0])).expand1().toJava(out);
+        new CharParser(MetaGrammar.make()).parse(new FileInputStream(args[0])).expand1().toJava(out);
         out.append("\n        // DO NOT EDIT STUFF ABOVE: IT IS AUTOMATICALLY GENERATED\n");
 
         for(String s = br.readLine(); s != null; s = br.readLine()) out.append(s+"\n");