checkpoint
authoradam <adam@megacz.com>
Fri, 28 Jul 2006 03:13:23 +0000 (23:13 -0400)
committeradam <adam@megacz.com>
Fri, 28 Jul 2006 03:13:23 +0000 (23:13 -0400)
darcs-hash:20060728031323-5007d-6eba60979bf9da3d465f8e2ab9e34d463d67793d.gz

12 files changed:
TODO
src/edu/berkeley/sbp/Ambiguous.java
src/edu/berkeley/sbp/GSS.java
src/edu/berkeley/sbp/Input.java
src/edu/berkeley/sbp/ParseFailed.java
src/edu/berkeley/sbp/Parser.java
src/edu/berkeley/sbp/chr/CharInput.java
src/edu/berkeley/sbp/misc/Cartesian.java
src/edu/berkeley/sbp/misc/Demo2.java
src/edu/berkeley/sbp/tib/Tib.java
src/edu/berkeley/sbp/util/ANSI.java
tests/java15.test

diff --git a/TODO b/TODO
index 321a8dc..280f875 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,18 +1,31 @@
 _____________________________________________________________________________
 Immediately
 
 _____________________________________________________________________________
 Immediately
 
-  - evil problems with: (x y? z /ws)
-     - it gets even more evil than that
+  - foo.add(x)
+    foo.add(y.andnot(x)) ==> this is broken
 
   - Annotation Tutorial
 
 
   - Annotation Tutorial
 
+  - Get at least *some* sort of moderate improvement in the error messages
+
+  ..................................................
+
+  - evil problems with: (x y? z /ws)
+     - it gets even more evil than that
+     - basically, follow restrictions are not honored when the element
+       matches against the empty string
 
 ______________________________________________________________________________
 v1.1
 
 
 ______________________________________________________________________________
 v1.1
 
+  - precedes restrictions ("<-")
+
   - MUST HAVE BETTER ERROR MESSAGES
      - use for developing java15.g
   - MUST HAVE BETTER ERROR MESSAGES
      - use for developing java15.g
+
   - java15.g
   - java15.g
+     - once this is ready, do big announcement
+
   - topology no longer needed as an arg to parser?
 
   - broader regression testing (for stuff like error messages, etc)
   - topology no longer needed as an arg to parser?
 
   - broader regression testing (for stuff like error messages, etc)
@@ -27,7 +40,7 @@ v1.1
 
 
 ______________________________________________________________________________
 
 
 ______________________________________________________________________________
-v1.1
+v1.2
 
   - finalize metagrammar and rdp-op's
   - write some grammars
 
   - finalize metagrammar and rdp-op's
   - write some grammars
index 8618b9e..bd87fd9 100644 (file)
@@ -9,8 +9,13 @@ import java.util.*;
 
 /** if ambiguity checking is enabled, this exception is thrown to signal that the parse was ambiguous */
 public class Ambiguous extends Exception {
 
 /** if ambiguity checking is enabled, this exception is thrown to signal that the parse was ambiguous */
 public class Ambiguous extends Exception {
+
     final Forest<?> ambiguity;
     private final HashSet<Tree<?>> ht;
     final Forest<?> ambiguity;
     private final HashSet<Tree<?>> ht;
+
+    /**
+     *  @param ht a specially-constructed set of trees with shared nodes replaced by '*'
+     */
     Ambiguous(Forest<?> ambiguity, HashSet<Tree<?>> ht) {
         this.ambiguity = ambiguity;
         this.ht = ht;
     Ambiguous(Forest<?> ambiguity, HashSet<Tree<?>> ht) {
         this.ambiguity = ambiguity;
         this.ht = ht;
@@ -18,13 +23,14 @@ public class Ambiguous extends Exception {
 
     public Forest<?> getAmbiguity() { return ambiguity; }
 
 
     public Forest<?> getAmbiguity() { return ambiguity; }
 
+    /** WARNING: this method is not considered part of the "stable API"; it may be removed in the future */
+    public Input.Region getRegion() { return ambiguity.getRegion(); }
+
     public String toString() {
     public String toString() {
-        // FIXME: print the input region that was ambiguously matched
         StringBuffer sb = new StringBuffer();
         sb.append("unresolved ambiguity at "+ambiguity.getRegion()+"; shared subtrees are shown as \"*\" ");
         StringBuffer sb = new StringBuffer();
         sb.append("unresolved ambiguity at "+ambiguity.getRegion()+"; shared subtrees are shown as \"*\" ");
-        //sb.append("\noffending text: ");
         for(Tree<?> result : ht) {
         for(Tree<?> result : ht) {
-            sb.append("\n  possibility: ");
+            sb.append("\n    possibility: ");
             StringBuffer sb2 = new StringBuffer();
             result.toPrettyString(sb2);
             sb.append(StringUtil.indent(sb2.toString(), 15));
             StringBuffer sb2 = new StringBuffer();
             result.toPrettyString(sb2);
             sb.append(StringUtil.indent(sb2.toString(), 15));
index 217889b..b36b293 100644 (file)
@@ -18,7 +18,9 @@ class GSS {
     int resets = 0;
     int waits = 0;
     
     int resets = 0;
     int waits = 0;
     
-    public GSS() { }
+    Input input;
+
+    public GSS(Input input) { this.input = input; }
 
     private Phase.Node[] reducing_list = null;
 
 
     private Phase.Node[] reducing_list = null;
 
@@ -53,11 +55,15 @@ class GSS {
         private Phase prev;
         private Input.Location location;
         private Input.Location nextLocation;
         private Phase prev;
         private Input.Location location;
         private Input.Location nextLocation;
+        private Input.Location prevLocation;
+        
         public final Parser parser;
 
         private Forest forest;
 
         public final Parser parser;
 
         private Forest forest;
 
-        public Phase(Phase prev, Parser parser, Phase previous, Tok token, Input.Location location, Input.Location nextLocation, Forest forest) throws ParseFailed {
+        public Phase(Phase prev, Parser parser, Phase previous, Tok token, Input.Location location,
+                     Input.Location nextLocation, Forest forest) throws ParseFailed {
+            this.prevLocation = prev==null ? location : prev.getLocation();
             this.prev = prev;
             this.forest = forest;
             this.parser = parser;
             this.prev = prev;
             this.forest = forest;
             this.parser = parser;
@@ -88,11 +94,15 @@ class GSS {
         public boolean isDone() throws ParseFailed {
             if (token != null) return false;
             if (token==null && finalResult==null)
         public boolean isDone() throws ParseFailed {
             if (token != null) return false;
             if (token==null && finalResult==null)
-                throw new ParseFailed(ParseFailed.error(ANSI.red("unexpected end of file\n"), token, hash.values()), getLocation());
+                throw new ParseFailed(ParseFailed.error(("unexpected end of file\n"),
+                                                        token, hash.values()),
+                                      getLocation().createRegion(getLocation()), input);
             return true;
         }
 
             return true;
         }
 
+        public Input.Location getPrevLocation() { return prevLocation; }
         public Input.Location getLocation() { return location; }
         public Input.Location getLocation() { return location; }
+        public Input.Region   getRegion() { return getPrevLocation().createRegion(getLocation()); }
         public Input.Location getNextLocation() { return nextLocation; }
 
         /** add a new node (merging with existing nodes if possible)
         public Input.Location getNextLocation() { return nextLocation; }
 
         /** add a new node (merging with existing nodes if possible)
@@ -243,14 +253,14 @@ class GSS {
             }
 
             if (!good && token!=null)
             }
 
             if (!good && token!=null)
-                throw new ParseFailed(ParseFailed.error(ANSI.red("unexpected character ")+" \'"+
+                throw new ParseFailed(ParseFailed.error(("unexpected character ")+" \'"+
                                                         ANSI.purple(StringUtil.escapify(token+"", "\\\'\r\n"))+
                                                         "\' encountered at "+
                                                         ANSI.purple(StringUtil.escapify(token+"", "\\\'\r\n"))+
                                                         "\' encountered at "+
-                                                        ANSI.green(getLocation())+"\n", token, hash.values()),
-                                        getLocation());
+                                                        ANSI.green(next.getRegion())+"\n", token, hash.values()),
+                                        next.getRegion(), input);
             if (token==null && finalResult==null)
             if (token==null && finalResult==null)
-                throw new ParseFailed(ParseFailed.error(ANSI.red("unexpected end of file\n"), token, hash.values()),
-                                        getLocation());
+                throw new ParseFailed(ParseFailed.error(("unexpected end of file at "+getLocation()+"\n"), token, hash.values()),
+                                      getLocation().createRegion(getLocation()), input);
         }
 
 
         }
 
 
@@ -348,7 +358,7 @@ class GSS {
                     for(Node child : ((Forest.Many<?>)result).parents) {
                         if (only != null && child!=only) continue;
                         holder[pos] = result;
                     for(Node child : ((Forest.Many<?>)result).parents) {
                         if (only != null && child!=only) continue;
                         holder[pos] = result;
-                        if (pos==0) child.finish(r, r.rewrite(child.phase().getNextLocation().createRegion(target.getLocation())), target);
+                        if (pos==0) child.finish(r, r.rewrite(child.phase().getLocation().createRegion(target.getLocation())), target);
                         else        child.reduce(r, pos-1, target, null);
                     }
 
                         else        child.reduce(r, pos-1, target, null);
                     }
 
index c16947d..6e4b0ee 100644 (file)
@@ -17,6 +17,15 @@ public interface Input<Token> {
     /** returns the location the input stream is currently at */
     public Location<Token> getLocation();
 
     /** returns the location the input stream is currently at */
     public Location<Token> getLocation();
 
+    /**
+     *  <b>Optional:</b> <i>If possible</i>, this method will return a
+     *  <60 char long rendering of the input region (for example, if
+     *  the input is a region of characters, it would be those
+     *  characters, possibly with ellipses in the middle to truncate
+     *  the length) -- otherwise, returns null.
+     */
+    public abstract String showRegion(Region<Token> r);
+
     /** <font color=purple>a location (position) in the input stream -- <i>between tokens</i></font> */
     public static interface Location<Token> extends Comparable<Location> {
 
     /** <font color=purple>a location (position) in the input stream -- <i>between tokens</i></font> */
     public static interface Location<Token> extends Comparable<Location> {
 
@@ -24,10 +33,29 @@ public interface Input<Token> {
         public Region<Token> createRegion(Location<Token> loc);
 
         public String toString();
         public Region<Token> createRegion(Location<Token> loc);
 
         public String toString();
+
+        /** the location following this one */
+        public Location next();
+
+        /** the location preceding this one */
+        public Location prev();
     }
 
     /** <font color=purple>a contiguous set of <tt>Location</tt>s</font> */
     public static interface Region<Token> /* implements Topology<Location<Tok>> */ {
     }
 
     /** <font color=purple>a contiguous set of <tt>Location</tt>s</font> */
     public static interface Region<Token> /* implements Topology<Location<Tok>> */ {
+
+        /**
+         *  the toString() method of Region should return a <80char
+         *  "rendition" of the input region, if possible
+         */
+        public abstract String toString();
+        
+        /** The location of the start of this region */
+        public abstract Location<Token> getStart();
+
+        /** The location of the end of this region */
+        public abstract Location<Token> getEnd();
+
     }
 
 }
     }
 
 }
index 27f87e8..d5474ae 100644 (file)
@@ -13,11 +13,43 @@ import java.util.*;
 public class ParseFailed extends Exception {
 
     private final Input.Location location;
 public class ParseFailed extends Exception {
 
     private final Input.Location location;
+    private final Input.Region region;
+    private final Input input;
     private final String message;
     private final String message;
-    ParseFailed() { this("", null); }
-    ParseFailed(String message, Input.Location loc) { this.location = loc; this.message = message; }
+    ParseFailed() { this("", null, null); }
+    ParseFailed(String message, Input.Region region, Input input) {
+        this.region = region;
+        this.location = region.getStart();
+        this.message = message;
+        this.input = input;
+    }
     public Input.Location getLocation() { return location; }
     public Input.Location getLocation() { return location; }
-    public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; }
+    private Input.Region getRegion() { return region; }
+    public String toString() {
+        Input.Location before = getRegion().getStart();
+        for(int i=0; i<10; i++) before = before.prev() == null ? before : before.prev();
+        Input.Location after = getRegion().getEnd();
+        for(int i=0; i<10; i++) after = after.next() == null ? after : after.next();
+        StringBuilder ret = new StringBuilder();
+        ret.append(message);
+        ret.append('\n');
+        ret.append("      at: ");
+        ret.append(getRegion()+"");
+        if (input != null) {
+            ret.append('\n');
+            ret.append("    text: ");
+            String first = input.showRegion(before.createRegion(getRegion().getStart()));
+            ret.append(first);
+            String second = input.showRegion(getRegion());
+            ret.append(ANSI.red(second));
+            ret.append(input.showRegion(getRegion().getEnd().createRegion(after)));
+            ret.append('\n');
+            ret.append("          ");
+            for(int i=0; i<first.length(); i++) ret.append(' ');
+            for(int i=0; i<second.length(); i++) ret.append(ANSI.red("^"));
+        }
+        return ret.toString();
+    }
 
     // FIXME
     private static HashSet<GSS.Phase.Node> touched = new HashSet<GSS.Phase.Node>();
 
     // FIXME
     private static HashSet<GSS.Phase.Node> touched = new HashSet<GSS.Phase.Node>();
index 9db0bf9..34d7da9 100644 (file)
@@ -25,7 +25,7 @@ public abstract class Parser<Token, NodeType> {
 
     /** parse <tt>input</tt>, and return the shared packed parse forest (or throw an exception) */
     public Forest<NodeType> parse(Input<Token> input) throws IOException, ParseFailed {
 
     /** parse <tt>input</tt>, and return the shared packed parse forest (or throw an exception) */
     public Forest<NodeType> parse(Input<Token> input) throws IOException, ParseFailed {
-        GSS gss = new GSS();
+        GSS gss = new GSS(input);
         Input.Location loc = input.getLocation();
         Token tok = input.next();
         GSS.Phase current = gss.new Phase<Token>(null, this, null, tok, loc, input.getLocation(), null);
         Input.Location loc = input.getLocation();
         Token tok = input.next();
         GSS.Phase current = gss.new Phase<Token>(null, this, null, tok, loc, input.getLocation(), null);
index 6dd9d7b..65b2b3e 100644 (file)
@@ -21,15 +21,40 @@ public class CharInput extends Cartesian.Input<Character> {
     
     boolean cr = false;
     private int count = 0;
     
     boolean cr = false;
     private int count = 0;
+    private StringBuilder cache = new StringBuilder();
+    
+    public void setCacheEnabled(boolean enabled) {
+        if (!enabled) cache = null;
+        else if (cache == null) cache = new StringBuilder();
+    }
+
     public boolean   isCR() { return cr; }
     public Character _next() throws IOException {
         cr = false;
         int i = r.read();
     public boolean   isCR() { return cr; }
     public Character _next() throws IOException {
         cr = false;
         int i = r.read();
-        if (i==-1) { System.err.print("\r...done       \r"); return null; }
+        if (i==-1) { /*System.err.print("\r...done       \r"); */return null; }
         char c = (char)i;
         char c = (char)i;
+        if (cache != null) cache.append(c);
         cr = c=='\n';
         cr = c=='\n';
+        /*
         if ((count++) % 100 == 0)
          System.err.print("  " + count + "\r");
         if ((count++) % 100 == 0)
          System.err.print("  " + count + "\r");
+        */
         return c;
     }
         return c;
     }
+
+    public String showRegion(Region<Character> rc) {
+        if (cache == null) return null;
+        Cartesian.Region r = (Cartesian.Region)rc;
+        int start = r.getStart().getScalar()+1;
+        int end = r.getEnd().getScalar()+1;
+        if (end > cache.length()) end = cache.length();
+        String ret;
+        if (end-start < 60) ret = cache.substring(start, end);
+        else ret = cache.substring(start, start+25) +
+                 "..." +
+                 cache.substring(end-25, end);
+        return StringUtil.escapify(ret, "\n\r");
+    }
+
 }
 }
index 50ddbab..2c32553 100644 (file)
@@ -17,12 +17,13 @@ public class Cartesian {
         public abstract boolean isCR();
 
         long then = 0;
         public abstract boolean isCR();
 
         long then = 0;
-        private Cartesian.Location location = new Cartesian.Location(0, 1);
+        private Cartesian.Location location = new Cartesian.Location();
         public  edu.berkeley.sbp.Input.Location    getLocation() { return location; }
 
         public Token next() throws IOException {
         public  edu.berkeley.sbp.Input.Location    getLocation() { return location; }
 
         public Token next() throws IOException {
-            int line  = location.getRow();
-            int col   = location.getCol();
+            int line   = location.getRow();
+            int col    = location.getCol();
+           int scalar = location.getScalar();
             Token t = _next();
             if (t==null) return null;
             String s = "  line "+line+", col " + col;
             Token t = _next();
             if (t==null) return null;
             String s = "  line "+line+", col " + col;
@@ -39,19 +40,32 @@ public class Cartesian {
             } else {
                 col++;
             }
             } else {
                 col++;
             }
-            location = new Cartesian.Location(col, line);
+            location.next = new Cartesian.Location(col, line, scalar+1);
+            location.next.prev = location;
+            location = location.next;
             return t;
         }
             return t;
         }
+
+        public String showRegion(Input.Region<Token> region) {
+            return null;
+        }
     }
 
     /** an implementation of Location for a cartesian grid (row, col) */
     public static class Location<Tok> implements Input.Location<Tok>, Comparable<Input.Location> {
         protected final int row;
         protected final int col;
     }
 
     /** an implementation of Location for a cartesian grid (row, col) */
     public static class Location<Tok> implements Input.Location<Tok>, Comparable<Input.Location> {
         protected final int row;
         protected final int col;
+        protected final int scalar;
+        Location<Tok> next = null;
+        Location<Tok> prev = null;
+        public Location<Tok> next() { return next; }
+        public Location<Tok> prev() { return prev; }
         public String toString() { return row+":"+col; }
         public int getCol() { return col; }
         public int getRow() { return row; }
         public String toString() { return row+":"+col; }
         public int getCol() { return col; }
         public int getRow() { return row; }
-        public Location(int col, int row) { this.row = row; this.col = col; }
+        public int getScalar() { return scalar; }
+        public Location() { this(-1, 1, 0); }
+        public Location(int col, int row, int scalar) { this.row = row; this.col = col; this.scalar = scalar; }
         public int compareTo(Input.Location loc) throws ClassCastException {
             if (!(loc instanceof Cartesian.Location)) throw new ClassCastException(loc.getClass().getName());
             Location<Tok> c = (Location<Tok>)loc;
         public int compareTo(Input.Location loc) throws ClassCastException {
             if (!(loc instanceof Cartesian.Location)) throw new ClassCastException(loc.getClass().getName());
             Location<Tok> c = (Location<Tok>)loc;
@@ -68,7 +82,10 @@ public class Cartesian {
     public static class Region<Tok> implements Input.Region<Tok> {
         public final Location<Tok> start;
         public final Location<Tok> end;
     public static class Region<Tok> implements Input.Region<Tok> {
         public final Location<Tok> start;
         public final Location<Tok> end;
+        public Location<Tok> getStart() { return start; }
+        public Location<Tok> getEnd() { return end; }
         public String toString() {
         public String toString() {
+            if (start.row==end.row && start.col==end.col) return start+"";
             if (start.row==end.row) return start.row+":"+(start.col+"-"+end.col);
             return start+"-"+end;
         }
             if (start.row==end.row) return start.row+":"+(start.col+"-"+end.col);
             return start+"-"+end;
         }
index 60bd6ee..487a896 100644 (file)
@@ -30,7 +30,7 @@ public class Demo2 {
         expr.add(multSequence);
         expr.add(Sequence.create(atom('0', '9')));
 
         expr.add(multSequence);
         expr.add(Sequence.create(atom('0', '9')));
 
-        String input = "(1+3*8)*7";
+        edu.berkeley.sbp.chr.CharInput input = new edu.berkeley.sbp.chr.CharInput("(1+3*8)*7");
 
         System.out.println("input:  \""+input+"\"");
 
 
         System.out.println("input:  \""+input+"\"");
 
@@ -39,7 +39,12 @@ public class Demo2 {
         System.out.println("grammar: \n"+sb);
 
         Forest f = new edu.berkeley.sbp.chr.CharParser(expr).parse(input);
         System.out.println("grammar: \n"+sb);
 
         Forest f = new edu.berkeley.sbp.chr.CharParser(expr).parse(input);
-        System.out.println("output: "+f.expand1().toPrettyString());
+        try {
+            System.out.println("output: "+f.expand1().toPrettyString());
+        } catch (Ambiguous a) {
+            System.err.println(a.toString());
+            System.err.println(" ambiguous text: " + input.showRegion(a.getRegion()));
+        }
     }
 
 }
     }
 
 }
index 2398c5c..a3fd568 100644 (file)
@@ -24,6 +24,8 @@ import java.io.*;
  */
 public class Tib implements Input<Character> {
 
  */
 public class Tib implements Input<Character> {
 
+    public String showRegion(Region<Character> r) { return null; }
+
     public Tib(String s) throws IOException { this(new StringReader(s)); }
     public Tib(Reader r) throws IOException { this(new BufferedReader(r)); }
     public Tib(InputStream is) throws IOException { this(new BufferedReader(new InputStreamReader(is))); }
     public Tib(String s) throws IOException { this(new StringReader(s)); }
     public Tib(Reader r) throws IOException { this(new BufferedReader(r)); }
     public Tib(InputStream is) throws IOException { this(new BufferedReader(new InputStreamReader(is))); }
@@ -40,7 +42,8 @@ public class Tib implements Input<Character> {
 
     int _row = 1;
     int _col = 0;
 
     int _row = 1;
     int _col = 0;
-    public Input.Location getLocation() { return new Cartesian.Location(_col, _row); }
+    int _scalar = 0;
+    public Input.Location getLocation() { return new Cartesian.Location(_col, _row, _scalar); }
     private BufferedReader br;
 
     char left = CharAtom.left;
     private BufferedReader br;
 
     char left = CharAtom.left;
@@ -81,6 +84,7 @@ public class Tib implements Input<Character> {
                 return null;
             }
             c = (char)i;
                 return null;
             }
             c = (char)i;
+            _scalar++;
             if (c=='\n') { _row++; _col=0; }
             else         _col++;
         }
             if (c=='\n') { _row++; _col=0; }
             else         _col++;
         }
index ecd9b43..a3304f0 100644 (file)
@@ -4,8 +4,8 @@ package edu.berkeley.sbp.util;
 public class ANSI {
     //public static String black(Object o) { return "\033[30m"+o+"\033[0m"; }
     public static String black(Object o) { return o+""; }
 public class ANSI {
     //public static String black(Object o) { return "\033[30m"+o+"\033[0m"; }
     public static String black(Object o) { return o+""; }
-    //public static String red(Object o) { return "\033[31m"+o+"\033[0m"; }
-    public static String red(Object o) { return o+""; }
+    public static String red(Object o) { return "\033[31m"+o+"\033[0m"; }
+    //public static String red(Object o) { return o+""; }
     //public static String green(Object o) { return "\033[32m"+o+"\033[0m"; }
     public static String green(Object o) { return o+""; }
     //public static String yellow(Object o) { return "\033[33m"+o+"\033[0m"; }
     //public static String green(Object o) { return "\033[32m"+o+"\033[0m"; }
     public static String green(Object o) { return o+""; }
     //public static String yellow(Object o) { return "\033[33m"+o+"\033[0m"; }
index 976fb75..b52f1fa 100644 (file)
@@ -7,6 +7,6 @@ public class Baz < A extends Object , Q super Foo<Bar<Baz>,Bop> > {
   }
 
   protected abstract int bar(int c);
   }
 
   protected abstract int bar(int c);
-  protected abstract int bop(  );
+  protected abstract int bop( );
 
 
-}
+}
\ No newline at end of file