checkpoint
authoradam <adam@megacz.com>
Tue, 18 Jul 2006 06:23:44 +0000 (02:23 -0400)
committeradam <adam@megacz.com>
Tue, 18 Jul 2006 06:23:44 +0000 (02:23 -0400)
darcs-hash:20060718062344-5007d-2b743714c33c282045381476353406035cf276c3.gz

TODO
src/edu/berkeley/sbp/Atom.java
src/edu/berkeley/sbp/Repeat.java
src/edu/berkeley/sbp/Sequence.java
src/edu/berkeley/sbp/chr/CharTopology.java
src/edu/berkeley/sbp/meta/MetaGrammarBindings.java
src/edu/berkeley/sbp/util/StringUtil.java

diff --git a/TODO b/TODO
index 31dbd1d..a6d3307 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,7 +1,8 @@
 _____________________________________________________________________________
 Immediately
 
-  * we can nuke Atom.toAtom() now!
+  - needs/hates/follow API ugliness
+
   - Topology crap is kinda messed up
 
   - do Forest/Tree still need a Region?
index 6c7a25e..98726c1 100644 (file)
@@ -28,17 +28,5 @@ public abstract class Atom<T> extends Element implements Topology<T> {
     public int               hashCode()                 { return top().hashCode(); }
     public boolean           equals(Object o)           { return o != null && o instanceof Atom && ((Atom)o).top().equals(top()); }
 
-    /** if all expressions matching <tt>e</tt> are exactly one token
-     *  long, <b>attempt to</b> return an Atom representing that token
-     *  (undecidable in general; only works in trivial cases)
-     */
-    public static Topology toAtom(Element e) {
-        if (e instanceof Atom) return (Atom)e;
-        if (e instanceof Sequence) return ((Sequence)e).toAtom();
-        Topology ret = null;
-        for(Sequence s : (Union)e)
-            ret = ret==null ? toAtom(s) : ret.union(s.toAtom());
-        return ret;
-    }
 }
 
index c85bfc6..2028847 100644 (file)
@@ -52,7 +52,7 @@ class Repeat extends Union {
 
 
     /** an atom which tracks the inverse of some other atom */
-    private static class Invert<T extends Input> extends Atom<T> {
+    static class Invert<T extends Input> extends Atom<T> {
         private final Atom<T> a;
         public Invert(Atom<T> a) { this.a = a; }
         public Topology<T> top() { return a.complement(); }
index 091f7ae..31d8f29 100644 (file)
@@ -50,14 +50,8 @@ public abstract class Sequence extends Element implements Iterable<Element> {
 
     ////////////////////////////////////////////////////////////////////////////////
 
-    public Element follow = null;
-    public final Topology follow() { return follow==null ? null : Atom.toAtom(follow); }
-
-    Topology toAtom() {
-        if (elements.length!=1)
-            throw new RuntimeException("cannot invoke toAtom() on a Sequence with " + elements.length + " elements: " + this);
-        return Atom.toAtom(elements[0]);
-    }
+    public Atom follow = null;
+    public final Topology follow() { return follow; }
 
     public Sequence and(Sequence s) { Sequence ret = dup(); ret.needs.add(s); s.needed.add(ret); return ret; }
     public Sequence not(Sequence s) { Sequence ret = dup(); ret.hates.add(s); s.hated.add(ret); return ret; }
index 8445eb3..cd482de 100644 (file)
@@ -35,6 +35,8 @@ public class CharTopology extends IntegerTopology<Character> implements Functor<
         return sb.toString();
     }
 
-    private String esc(char c) { return StringUtil.escapify(c+"", "[]-~\\\"\'\n\r"); }
+    private String esc(char c) {
+        return StringUtil.escapify(c+"", "[]-~\\\"\'\n\r");
+    }
 
 }
index 3dd0879..835d79e 100644 (file)
@@ -64,6 +64,13 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
 
     public abstract static class UnionNode extends ElementNode {
         public Seq[][] sequences;
+        public Atom toAtom(Context cx) {
+            Atom ret = null;
+            for(Seq[] ss : sequences)
+                for(Seq s : ss)
+                    ret = ret==null ? s.toAtom(cx) : infer(ret.union(s.toAtom(cx)));
+            return ret;
+        }
         public void build(Context cx, Union u, NonTerminalNode cnt) {
             HashSet<Sequence> bad2 = new HashSet<Sequence>();
             for(int i=0; i<sequences.length; i++) {
@@ -192,8 +199,15 @@ 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");
+            return elements[0].toAtom(cx);
+        }
         public Seq tag(String tag) { this.tag = prefix+tag; return this; }
-        public Seq follow(ElementNode follow) { this.follow = follow; return this; }
+        public Seq follow(ElementNode follow) {
+            this.follow = follow;
+            return this;
+       }
         public Seq dup() {
             Seq ret = new Seq(elements);
             ret.and.addAll(and);
@@ -243,22 +257,22 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
                     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,false));
+                            else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els, false));
                     if (idx != -1) ret = Sequence.singleton(els, idx);
                     else           ret = Sequence.drop(els, false);
                 }
             }
             if (this.follow != null)
-                ret.follow = infer(this.follow.build(cx, null));
+                ret.follow = this.follow.toAtom(cx);
             ret.lame = this.lame;
             return ret;
         }
     }
-    public static @bind.as("&")   Seq  and2(Seq s,        Seq a) { return s.and(a); }
-    public static @bind.as("&~")  Seq  andnot2(Seq s,     Seq a) { return s.andnot(a); }
-    public static @bind.as("->")  Seq  arrow(Seq s, ElementNode e)                { return s.follow(e); }
-    public static @bind.as("::")  Seq  tag(String tagname, Seq s)        { return s.tag(tagname); }
-    public static @bind.as("/")   Seq  slash(Seq s, ElementNode e)                { return s.separate(e); }
+    public static @bind.as("&")   Seq  and2(Seq s,        Seq a)   { return s.and(a); }
+    public static @bind.as("&~")  Seq  andnot2(Seq s,     Seq a)   { return s.andnot(a); }
+    public static @bind.as("->")  Seq  arrow(Seq s, ElementNode e) { return s.follow(e); }
+    public static @bind.as("::")  Seq  tag(String tagname, Seq s)  { return s.tag(tagname); }
+    public static @bind.as("/")   Seq  slash(Seq s, ElementNode e) { return s.separate(e); }
 
     public static Seq  seq(ElementNode[] elements)               { return new Seq(elements); }
     public static @bind.as("Elements")  Seq  seq2(ElementNode[] elements)               { return new Seq(elements); }
@@ -276,6 +290,9 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         public @bind.as("NonTerminalReference") NonTerminalReferenceNode(String nonTerminal) {
             this.nonTerminal = prefix + nonTerminal;
         }
+        public Atom toAtom(Context cx) {
+            return cx.grammar.get(nonTerminal).toAtom(cx);
+        }
         public Element build(Context cx, NonTerminalNode cnt) {
             if (!this.nonTerminal.startsWith(prefix)) nonTerminal = prefix + nonTerminal;
             Element ret = cx.get(nonTerminal);
@@ -285,13 +302,29 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
     }
 
     public static class Literal extends Constant {
-        public @bind Literal(@bind.arg String string) { super(CharAtom.string(string)); }
+        private String string;
+        public @bind Literal(@bind.arg String string) {
+            super(CharAtom.string(string));
+            this.string = string;
+        }
         public boolean drop() { return true; }
+        public Atom toAtom(Context cx) {
+            if (string.length()!=1) return super.toAtom(cx);
+            edu.berkeley.sbp.util.Range.Set set = new edu.berkeley.sbp.util.Range.Set();
+            set.add(string.charAt(0), string.charAt(0));
+            return CharAtom.set(set);
+        }
     }
 
     public static                     class CharClass            extends ElementNode {
         Range[] ranges;
         public @bind.as("[") CharClass(Range[] ranges) { this.ranges = ranges; }
+        public Atom toAtom(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);
+            return CharAtom.set(set);
+        }
         public Element build(Context cx, NonTerminalNode cnt) {
             edu.berkeley.sbp.util.Range.Set set = new edu.berkeley.sbp.util.Range.Set();
             for(Range r : ranges)
@@ -322,12 +355,16 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         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 Atom toAtom(Context cx) {
+            if (sep != null) return super.toAtom(cx);
+            return e.toAtom(cx);
+        }
         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())
                 : sep==null
-                ? Sequence.repeatMaximal(infer(e.build(cx, null)), zero, many, cx.rm.repeatTag())
-                : Sequence.repeatMaximal(e.build(cx, null), zero, many, infer(sep.build(cx, null)), cx.rm.repeatTag());
+                ? Sequence.repeatMaximal(e.toAtom(cx), zero, many, cx.rm.repeatTag())
+                : Sequence.repeatMaximal(e.build(cx, null), zero, many, sep.toAtom(cx), cx.rm.repeatTag());
         }
     }
 
@@ -362,9 +399,12 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
     }
 
     public static @bind.as("~")   ElementNode tilde(final ElementNode e) {
-        return new PostProcess(e) {
-                public Element postProcess(Element e) {
-                    return infer((Topology<Character>)Atom.toAtom(e).complement().minus(CharAtom.braces));
+        return new ElementNodeWrapper(e) {
+                public Atom toAtom(Context cx) {
+                    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));
                 } }; }
 
     public static @bind.as("Word")        String word(String s) { return s; }
@@ -374,7 +414,7 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
     public static @bind.as("\n")          String retur() { return "\n"; }
     public static @bind.as("\r")          String lf() { return "\r"; }
 
-    static Atom infer(Element e)  { return infer((Topology<Character>)Atom.toAtom(e)); }
+    //static Atom infer(Element e)  { return infer((Topology<Character>)Atom.toAtom(e)); }
     static Atom infer(Topology<Character> t) { return new CharAtom(new CharTopology(t)); }
 
     public static class Context {
@@ -425,6 +465,7 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         public String getLabel() { return null; }
         public String getOwnerTag() { return null; }
         public boolean drop() { return false; }
+        public Atom toAtom(Context cx) { throw new Error("can't convert a " + this.getClass().getName() + " to an atom"); }
         public abstract Element build(Context cx, NonTerminalNode cnt);
     }
 
@@ -434,6 +475,7 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         public String getLabel() { return _e.getLabel(); }
         public String getOwnerTag() { return _e.getOwnerTag(); }
         public boolean drop() { return _e.drop(); }
+        public Atom toAtom(Context cx) { return _e.toAtom(cx); }
         public Element build(Context cx, NonTerminalNode cnt) { return _e.build(cx, cnt); }
     }
 
@@ -441,10 +483,13 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         Element constant;
         public Constant(Element constant) { this.constant = constant; }
         public Element build(Context cx, NonTerminalNode cnt) { return constant; }
+        public Atom toAtom(Context cx) {
+            if (constant instanceof Atom) return ((Atom)constant);
+            return super.toAtom(cx);
+        }
     }
 
     public abstract static class PostProcess extends ElementNodeWrapper {
-        ElementNode e;
         public PostProcess(ElementNode e) { super(e); }
         public Element build(Context cx, NonTerminalNode cnt) { return postProcess(_e.build(cx, cnt)); }
         public abstract Element postProcess(Element e);
@@ -460,4 +505,11 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings {
         public Label(String label, ElementNode e) { super(e); this.label = label; }
         public String getLabel() { return label; }
     }
+
+    static class Invert extends Atom {
+        private final Atom a;
+        public Invert(Atom a) { this.a = a; }
+        public Topology top() { return a.complement(); }
+        public String toString() { return "~"+a; }
+    }
 }
index d8de66d..7d8009d 100644 (file)
@@ -65,7 +65,11 @@ public class StringUtil {
                     case '\r':  sb.append("\\r"); continue;
                     default:    sb.append('\\');  break;
                 }
-            sb.append(c);
+            else if (c < 32 || c >= 127) {
+                sb.append("\\x"+((int)c));
+            } else {
+                sb.append(c);
+            }
         }
         return sb.toString();
     }