refactoring to eliminate Token.result()
authoradam <adam@megacz.com>
Mon, 2 Jan 2006 06:52:26 +0000 (01:52 -0500)
committeradam <adam@megacz.com>
Mon, 2 Jan 2006 06:52:26 +0000 (01:52 -0500)
darcs-hash:20060102065226-5007d-b8a300317328f76042b43c170df7e8569328f5bb.gz

src/edu/berkeley/sbp/Atom.java
src/edu/berkeley/sbp/Forest.java
src/edu/berkeley/sbp/GSS.java
src/edu/berkeley/sbp/Parser.java
src/edu/berkeley/sbp/Token.java
src/edu/berkeley/sbp/Walk.java
src/edu/berkeley/sbp/misc/CharToken.java
src/edu/berkeley/sbp/misc/MetaGrammar.java
src/edu/berkeley/sbp/misc/RegressionTests.java
src/edu/berkeley/sbp/tib/TibDoc.java

index 3b7ce1f..aac834b 100644 (file)
@@ -11,21 +11,13 @@ import edu.berkeley.sbp.*;
 public abstract class Atom<T extends Token> extends Element implements Topology<T> {
 
     protected abstract Topology<T> top();
+    public    abstract String toString();
 
     public Topology toAtom() { return this; }
 
-    /** equality is based on the underlying <tt>Topology</tt> */
-    public int hashCode() { return top().hashCode(); }
-    
-    /** equality is based on the underlying <tt>Topology</tt> */
-    public boolean equals(Object o) { return o != null && o instanceof Atom && ((Atom)o).top().equals(top()); }
-
-    /** declared abstract to force subclasses to override it in a useful manner */
-    public abstract String toString();
-
     // Topology Thunks //////////////////////////////////////////////////////////////////////////////
 
-    public Topology<T>       unwrap() { return top().unwrap(); }
+    public Topology<T>       unwrap()                   { return top().unwrap(); }
     public Topology<T>       empty()                    { return top().empty(); }
     public boolean           contains(T v)              { return top().contains(v); }
     public Topology<T>       intersect(Topology<T> t)   { return top().intersect(t); }
@@ -34,6 +26,8 @@ public abstract class Atom<T extends Token> extends Element implements Topology<
     public Topology<T>       complement()               { return top().complement(); }
     public boolean           disjoint(Topology<T> t)    { return top().disjoint(t); }
     public boolean           containsAll(Topology<T> t) { return top().containsAll(t); }
+    public int               hashCode()                 { return top().hashCode(); }
+    public boolean           equals(Object o)           { return o != null && o instanceof Atom && ((Atom)o).top().equals(top()); }
 
     // Subclasses //////////////////////////////////////////////////////////////////////////////
 
index 13ac199..8587dcb 100644 (file)
@@ -24,7 +24,7 @@ public abstract class Forest<T> {
     static <T> Forest<T>   singleton(Token.Location loc, Sequence creator)                       { return create(loc, null, new Forest[] { }, creator, false, true); }
     static <T> Forest<T>   singleton(Token.Location loc, Forest<T> body, Sequence creator)       { return create(loc, null, new Forest[] { body }, creator, false, true); }
     static <T> Forest<T>   leaf(Token.Location loc, T tag,                     Sequence creator) { return create(loc, tag, null, creator, false, false); }
-    static <T> Forest<T>   create(Token.Location loc, T tag, Forest<T>[] tokens, Sequence creator, boolean unwrap, boolean singleton) {
+    public static <T> Forest<T>   create(Token.Location loc, T tag, Forest<T>[] tokens, Sequence creator, boolean unwrap, boolean singleton) {
         return new MultiForest<T>(loc, tag, tokens, creator, unwrap, singleton);
     }
 
index d8c0fd4..2d9f6ff 100644 (file)
@@ -123,7 +123,7 @@ class GSS {
         }
 
         /** perform all shift operations, adding promoted nodes to <tt>next</tt> */
-        public void shift(Phase next) {
+        public void shift(Phase next, Forest result) {
             closed = true;
             Forest res = null;
             boolean ok = false;
@@ -137,7 +137,7 @@ class GSS {
                 if (!n.holder.valid()) continue;
                 if (token == null) continue;
                 for(Parser.Table.State st : n.state.getShifts(token)) {
-                    if (res == null) res = Forest.create(token.getLocation(), token.result(), null, null, false, false);
+                    if (res == null) res = result;
                     next.newNode(n, res, st, true, this);
                     ok = true;
                 }
index ab06889..6bf274d 100644 (file)
@@ -9,7 +9,7 @@ import java.util.*;
 import java.lang.reflect.*;
 
 /** a parser which translates streams of Tokens of type T into a Forest<R> */
-public class Parser<T extends Token, R> {
+public abstract class Parser<T extends Token, R> {
 
     private final Table pt;
 
@@ -24,16 +24,15 @@ public class Parser<T extends Token, R> {
         if (p.element() != null) reachable(p.element(), h);
     }
 
-    //public Parser(          Topology top) { this(new Table(   top)); }
-    //public Parser(String s, Topology top) { this(new Table(s, top)); }
-
     /**
      *  create a parser to parse the grammar with start symbol <tt>u</tt>
-     *  @param top a "sample" Topology<T> that can be cloned (FIXME, demanding this is lame)
      */
-    public Parser(Union u,  Topology<T> top) { this(new Table(u, top)); }
+    protected Parser(Union u)  { this.pt = new Table(u, top()); }
+    protected Parser(Table pt) { this.pt = pt; }
+
+    public abstract Forest<R> shiftedToken(T t);
+    public abstract Topology<T> top();
 
-    Parser(Table pt)               { this.pt = pt; }
 
     /** parse <tt>input</tt> for a exactly one unique result, throwing <tt>Ambiguous</tt> if not unique or <tt>Failed</tt> if none */
     public Tree<R> parse1(Token.Stream<T> input) throws IOException, Failed, Ambiguous { return parse(input).expand1(); }
@@ -46,7 +45,8 @@ public class Parser<T extends Token, R> {
         for(;;) {
             GSS.Phase next = gss.new Phase(current, input.next());
             current.reduce();
-            current.shift(next);
+            Forest forest = current.token==null ? null : shiftedToken((T)current.token);
+            current.shift(next, forest);
             if (current.isDone()) return (Forest<R>)current.finalResult;
             current.checkFailure();
             current = next;
@@ -80,12 +80,13 @@ public class Parser<T extends Token, R> {
 
     // Table //////////////////////////////////////////////////////////////////////////////
 
+    static class Top extends Union { public Top() { super("0"); } }
+
     /** an SLR(1) parse table which may contain conflicts */
     static class Table {
 
         private final Union start0 = new Top();
         private final Sequence start0seq;
-        static class Top extends Union { public Top() { super("0"); } }
         
         public final Walk.Cache cache = new Walk.Cache();
         
index 196f5ca..07edde3 100644 (file)
@@ -10,10 +10,6 @@ import edu.berkeley.sbp.*;
 /** a token of input -- note that this represents an <i>actual input token</i> rather than an <tt>Element</tt> which <i>matches</i> a token */
 public interface Token {
 
-    // FIXME!!! remove this
-    /** converts this <tt>Token</tt> into a standalone result (ie for a non-rewriting pattern) */
-    public String result();
-
     /** this is declared abstract as a way of forcing subclasses to provide a thoughtful implementation */
     public abstract String toString();
 
index 4f133a4..f8f8d4f 100644 (file)
@@ -138,10 +138,10 @@ abstract class Walk<T> {
             eof = false;
             cs = cso.empty();
 
-            if (e instanceof Parser.Table.Top) eof = true;
+            if (e instanceof Parser.Top) eof = true;
             for(Element x : all) {
                 boolean matched = false;
-                if (x instanceof Parser.Table.Top) walk(x); // because this symbol might not appear in any other Sequence
+                if (x instanceof Parser.Top) walk(x); // because this symbol might not appear in any other Sequence
                 if (!(x instanceof Sequence)) continue;
                 Sequence a = (Sequence)x;
                 Position mp = null;
index 143c708..eba6cbe 100644 (file)
@@ -13,6 +13,14 @@ public class CharToken implements Token, IntegerTopology.IntegerMappable {
 
     // Public //////////////////////////////////////////////////////////////////////////////
 
+    public static class CharToStringParser extends Parser<CharToken,String> {
+        public CharToStringParser(Union u) { super(u); }
+        public Topology<CharToken> top() { return new IntegerTopology<CharToken>(); }
+        public Forest<String> shiftedToken(CharToken ct) {
+            return Forest.create(ct.getLocation(), ct.result(), null, null, false, false);
+        }
+    }
+
     public static class CharRange extends Atom<CharToken> {
         private String esc(char c) { return StringUtil.escapify(c+"", "[]-~\\\"\'"); }
         private Topology<CharToken> t;
index fee813d..f6994ce 100644 (file)
@@ -274,7 +274,7 @@ public class MetaGrammar extends StringWalker {
         }
 
         out.append("\n        // DO NOT EDIT STUFF BELOW: IT IS AUTOMATICALLY GENERATED\n");
-        new Parser(MetaGrammar.make(), CharToken.top()).parse1(new CharToken.Stream(new InputStreamReader(new FileInputStream(args[0])))).toJava(out);
+        new CharToken.CharToStringParser(MetaGrammar.make()).parse1(new CharToken.Stream(new InputStreamReader(new FileInputStream(args[0])))).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");
index 1fd97f1..9429b69 100644 (file)
@@ -22,16 +22,16 @@ public class RegressionTests {
             //MetaGrammar mg0 = new MetaGrammar();
             //mg0.walk(MetaGrammar.meta);
             //System.out.println(mg0);
-            Tree<String> res = new Parser(MetaGrammar.make(), CharToken.top()).parse1(new CharToken.Stream(new InputStreamReader(new FileInputStream(s[0]))));
+            Tree<String> res = new CharToken.CharToStringParser(MetaGrammar.make()).parse1(new CharToken.Stream(new InputStreamReader(new FileInputStream(s[0]))));
             MetaGrammar mg = (MetaGrammar)new MetaGrammar().walk(res);
             //System.out.println(mg);
             Union meta = mg.done();
             SequenceInputStream sis = new SequenceInputStream(new FileInputStream(s[0]), new FileInputStream(s[1]));
-            res = new Parser(meta, CharToken.top()).parse1(new CharToken.Stream(new InputStreamReader(sis), "parsing " + s[1] + " using " + s[0]));
+            res = new CharToken.CharToStringParser(meta).parse1(new CharToken.Stream(new InputStreamReader(sis), "parsing " + s[1] + " using " + s[0]));
             Union testcasegrammar = ((MetaGrammar)new MetaGrammar("ts").walk(res)).done("ts");
             if (testcasegrammar==null) return;
             CharToken.Stream cs = new CharToken.Stream(new InputStreamReader(new FileInputStream(s[2])), "parsing " + s[2] + " using " + s[1]);
-            Parser parser = new Parser(testcasegrammar, CharToken.top());
+            Parser parser = new CharToken.CharToStringParser(testcasegrammar);
 
             if (profile) {
                 System.out.println("\nready...");
@@ -74,7 +74,7 @@ public class RegressionTests {
             return ret;
         }
         public boolean execute() throws Exception {
-            Forest<String> res = new Parser(grammar, CharToken.top()).parse(inp);
+            Forest<String> res = new CharToken.CharToStringParser(grammar).parse(inp);
             Collection<Tree<String>> results = res==null ? new HashSet<Tree<String>>() : res.expand(false);
             System.out.print("\r");
             if (results.size() == 0 && output.length > 0) {
index b44678f..f519729 100644 (file)
@@ -14,13 +14,13 @@ public class TibDoc {
     
     public static void main(String[] s) throws Exception {
         System.out.println("parsing " + s[0]);
-        Tree<String> res = new Parser(MetaGrammar.make(), CharToken.top()).parse1(new CharToken.Stream(new FileInputStream(s[0])));
+        Tree<String> res = new CharToken.CharToStringParser(MetaGrammar.make()).parse1(new CharToken.Stream(new FileInputStream(s[0])));
         MetaGrammar gram = (MetaGrammar)new Tib.Grammar().walk(res);
         //System.out.println(gram);
         Union mg = gram.done();
         
         System.out.println("\nparsing " + s[1]);
-        res = new Parser(mg, CharToken.top()).parse1(new Tib(new FileInputStream(s[1])));
+        res = new CharToken.CharToStringParser(mg).parse1(new Tib(new FileInputStream(s[1])));
         System.out.println(res);
     }