public class ParseFailed extends Exception {
private final Input.Location location;
+ private final Input.Region region;
+ private final Input input;
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 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>();