checkpoint
[sbp.git] / src / edu / berkeley / sbp / ParseFailed.java
index d46570b..d5474ae 100644 (file)
+// Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
+
 package edu.berkeley.sbp;
 import edu.berkeley.sbp.*;
+import edu.berkeley.sbp.Sequence.Position;
+import edu.berkeley.sbp.GSS.Phase;
+import edu.berkeley.sbp.GSS.Phase.Node;
 import edu.berkeley.sbp.util.*;
 import java.io.*;
 import java.util.*;
 
 /** thrown when the parser arrives at a state from which it is clear that no valid parse can result */
-public class ParseFailed extends RuntimeException {
-    private final Token.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;
-    public ParseFailed() { this("", null); }
-    public ParseFailed(String message, Token.Location loc) { this.location = loc; this.message = message; }
-    public Token.Location getLocation() { return location; }
-    public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; }
+    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; }
+    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>();
+    static <Tok> void complain(GSS.Phase<Tok>.Node n, HashMap<String,HashSet<String>> errors, boolean force) {
+        if (touched.contains(n)) return;
+        touched.add(n);
+        for(Position p : n.state) {
+            if (((p.isFirst() || p.isLast()) && !force)/* || p.owner().name==null*/) {
+                for(Node n2 : n.parents())
+                    complain(n2, errors, force | p.isFirst());
+            } else {
+                String seqname = p.owner()/*.name*/+"";
+                HashSet<String> hs = errors.get(seqname);
+                if (hs==null) errors.put(seqname, hs = new HashSet<String>());
+                hs.add(p.element()+"");
+            }
+        }
+    }
+
+    static String el(Object e) {
+        String s = e.toString();
+        if (s.length()==0 || s.charAt(0)!='\"' || s.charAt(s.length()-1)!='\"') return /*ANSI.yellow(s)*/s;
+        s = s.substring(1);
+        s = s.substring(0, s.length()-1);
+        StringBuffer ret = new StringBuffer();
+        for(int i=0; i<s.length(); i++) {
+            if (s.charAt(i)=='\\' && i<s.length()-1) ret.append(s.charAt(++i));
+            else ret.append(s);
+        }
+        return /*ANSI.purple(ret.toString())*/ret.toString();
+    }
+    static String error(String message, Object token, Iterable<Node> nodes) {
+        String lookAhead = token==null ? "<EOF>" : token.toString();
+        StringBuffer ret = new StringBuffer();
+        ret.append("\n  ");
+        ret.append(message);
+        /*
+        HashMap<String,HashSet<String>> errors = new HashMap<String,HashSet<String>>();
+        for(Node n : nodes) {
+            //System.out.println(n.state);
+            complain(n, errors, false);
+        }
+        for(String s : errors.keySet()) {
+            ret.append("    while parsing " + ANSI.yellow(s));
+            HashSet<String> hs = errors.get(s);
+            if (hs.size()==1) ret.append(" expected " + ANSI.yellow(el(hs.iterator().next())) + "\n");
+            else {
+                ret.append(" expected ");
+                boolean first = true;
+                for(String s2 : hs) {
+                    if (!first) ret.append(" or ");
+                    first = false;
+                    ret.append(ANSI.yellow(el(s2)));
+                }
+                ret.append("\n");
+            }
+        }
+        */
+        return ret.toString();
+    }
+
 }