From: adam Date: Sat, 29 Jul 2006 07:26:20 +0000 (-0400) Subject: vast improvement in error reporting X-Git-Tag: tag_for_25-Mar~91 X-Git-Url: http://git.megacz.com/?p=sbp.git;a=commitdiff_plain;h=62be1c1ae2ac13086b508e34eeffdb7e536d5b61 vast improvement in error reporting darcs-hash:20060729072620-5007d-fcd503f30c8f029b2a9502dd42cafe3db8d09b0d.gz --- diff --git a/src/edu/berkeley/sbp/GSS.java b/src/edu/berkeley/sbp/GSS.java index b36b293..5255a21 100644 --- a/src/edu/berkeley/sbp/GSS.java +++ b/src/edu/berkeley/sbp/GSS.java @@ -94,9 +94,13 @@ class GSS { public boolean isDone() throws ParseFailed { if (token != null) return false; if (token==null && finalResult==null) - throw new ParseFailed(ParseFailed.error(("unexpected end of file\n"), - token, hash.values()), - getLocation().createRegion(getLocation()), input); + ParseFailed.error("unexpected end of file", + getLocation(), + token, + hash.values(), + getLocation().createRegion(getLocation()), + input, + GSS.this); return true; } @@ -253,14 +257,22 @@ class GSS { } if (!good && token!=null) - throw new ParseFailed(ParseFailed.error(("unexpected character ")+" \'"+ - ANSI.purple(StringUtil.escapify(token+"", "\\\'\r\n"))+ - "\' encountered at "+ - ANSI.green(next.getRegion())+"\n", token, hash.values()), - next.getRegion(), input); + ParseFailed.error("unexpected character", + getLocation(), + token, + hash.values(), + getRegion(), + input, + GSS.this); + if (token==null && finalResult==null) - throw new ParseFailed(ParseFailed.error(("unexpected end of file at "+getLocation()+"\n"), token, hash.values()), - getLocation().createRegion(getLocation()), input); + ParseFailed.error("unexpected end of file", + getLocation(), + token, + hash.values(), + getLocation().createRegion(getLocation()), + input, + GSS.this); } diff --git a/src/edu/berkeley/sbp/ParseFailed.java b/src/edu/berkeley/sbp/ParseFailed.java index d5474ae..547ea95 100644 --- a/src/edu/berkeley/sbp/ParseFailed.java +++ b/src/edu/berkeley/sbp/ParseFailed.java @@ -16,62 +16,110 @@ public class ParseFailed extends Exception { private final Input.Region region; private final Input input; private final String message; - ParseFailed() { this("", null, null); } - ParseFailed(String message, Input.Region region, Input input) { + private final GSS gss; + ParseFailed() { this("", null, null, null); } + ParseFailed(String message, Input.Region region, Input input, GSS gss) { this.region = region; this.location = region.getStart(); this.message = message; this.input = input; + this.gss = gss; } 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= 'A' && c <= 'Z'); + } + + static void barf(HashMap sb, GSS.Phase.Node n, int indent, boolean skip, int count, Input.Location loc) { + if (count <= 0) { + barf(sb, n, indent, skip, loc); + } else { + for(GSS.Phase.Node nn : n.parents()) + barf(sb, nn, indent, skip, count-1, nn.phase().getPrevLocation()); + } + } + static void barf(HashMap sb, GSS.Phase.Node n, int indent, boolean skip, Input.Location loc) { + if (touched.contains(n)) return; + touched.add(n); + String s = ""; + for(int i=0; i< indent; i++) s += " "; + GSS.Phase.Node parent = n; + boolean done = false; + boolean alldone = false; + boolean go = false; + boolean force = false; + for(Position p : parent.state) { + if (skip) p = p.next(); + int raise = 0; + done = false; + while(p != null) { + if (p.isLast()) break; + if (important(p)) { + Input.Location l = sb.get(p.element()); + if (l == null || l.compareTo(loc) < 0) + sb.put(p.element(), loc); + done = true; + alldone = true; + } + /* + else if (p.pos-raise > 0) + barf(sb, n, indent, false, 1); + */ + if (!new Walk.Cache().possiblyEpsilon(p.element())) + break; + p = p.next(); + raise++; + if (p.isLast()) { + if (!done) barf(sb, n, indent, true, 1, loc); + break; + } + } + } + if (!alldone) barf(sb, n, indent, false, 1, loc); + } + + + // FIXME private static HashSet touched = new HashSet(); - static void complain(GSS.Phase.Node n, HashMap> errors, boolean force) { + static void complain(GSS.Phase.Node n, HashMap> errors, boolean force, int indent) { if (touched.contains(n)) return; touched.add(n); for(Position p : n.state) { - if (((p.isFirst() || p.isLast()) && !force)/* || p.owner().name==null*/) { + //if (!p.isLast() && !p.next().isLast()) continue; + if (((p.isFirst() || p.isLast()) && !force)/* || p.owner().name==null*/ || + !important(p)) { for(Node n2 : n.parents()) - complain(n2, errors, force | p.isFirst()); + complain(n2, errors, force /*| p.isFirst()*/, indent); } else { String seqname = p.owner()/*.name*/+""; HashSet hs = errors.get(seqname); if (hs==null) errors.put(seqname, hs = new HashSet()); - hs.add(p.element()+""); + String s = ""; + 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; + if (s.length()==0 || s.charAt(0)!='\"' || s.charAt(s.length()-1)!='\"') return ANSI.yellow(s); s = s.substring(1); s = s.substring(0, s.length()-1); StringBuffer ret = new StringBuffer(); @@ -79,36 +127,95 @@ public class ParseFailed extends Exception { if (s.charAt(i)=='\\' && i nodes) { + + static void error(String message, + Input.Location loc, + Object token, + Iterable nodes, + Input.Region region, + Input input, + GSS gss) throws ParseFailed{ String lookAhead = token==null ? "" : token.toString(); StringBuffer ret = new StringBuffer(); - ret.append("\n "); - ret.append(message); + ret.append(ANSI.bold(ANSI.red(message))); + if (token != null) { + ret.append(" \'"); + ret.append(ANSI.cyan(StringUtil.escapify(token+"", "\\\'\r\n"))); + ret.append("\'"); + } + ret.append(" at "); + ret.append(ANSI.yellow(region+"")); + if (input != null) { + ret.append('\n'); + ret.append(" text: "); + int budget = 60; + String second = input.showRegion(region); + budget -= second.length(); + Input.Location after = region.getEnd(); + for(int i=0; i<10; i++) after = after.next() == null ? after : after.next(); + String third = input.showRegion(region.getEnd().createRegion(after)); + budget -= third.length(); + Input.Location before = region.getStart(); + for(int i=0; i hm = new HashMap(); + for(Node no : nodes) + barf(hm, no, 0, false, /*region.getStart()*/loc); + ret.append("\n expected: "); + Set hs = hm.keySet(); + if (hs.size() == 1) { + ret.append(hs.iterator().next()); + } else { + int i=0; + for(Element s : hs) { + Input.Location loc2 = hm.get(s); + if (i==0) { + ret.append("" + ANSI.purple(s)); + } else { + ret.append("\n or " + ANSI.purple(s)); + } + Input.Region reg = loc2.createRegion(region.getStart()); + ret.append(" to match \"" + ANSI.cyan(input.showRegion(reg)) + "\" at " + ANSI.yellow(reg)); + i++; + } + } /* + ret.append("\n The author of SBP apologizes for the these nearly-useless error messages:\n\n"); HashMap> errors = new HashMap>(); for(Node n : nodes) { //System.out.println(n.state); - complain(n, errors, false); + complain(n, errors, false, 0); } for(String s : errors.keySet()) { ret.append(" while parsing " + ANSI.yellow(s)); HashSet hs = errors.get(s); - if (hs.size()==1) ret.append(" expected " + ANSI.yellow(el(hs.iterator().next())) + "\n"); + + if (hs.size()==1) ret.append("\n expected " + ANSI.yellow(el(hs.iterator().next())) + "\n\n"); else { - ret.append(" expected "); + ret.append("\n expected "); boolean first = true; for(String s2 : hs) { if (!first) ret.append(" or "); first = false; ret.append(ANSI.yellow(el(s2))); } - ret.append("\n"); + ret.append("\n\n"); } } */ - return ret.toString(); + throw new ParseFailed(ret.toString(), region, input, gss); } } diff --git a/src/edu/berkeley/sbp/Union.java b/src/edu/berkeley/sbp/Union.java index 51002ab..5ff00d6 100644 --- a/src/edu/berkeley/sbp/Union.java +++ b/src/edu/berkeley/sbp/Union.java @@ -19,8 +19,8 @@ import java.lang.ref.*; */ public class Union extends Element implements Iterable { - private final String name; - private final boolean synthetic; + /*private*/ final String name; + /*private*/ final boolean synthetic; private boolean viewed = false; private final List alternatives = new ArrayList(); diff --git a/src/edu/berkeley/sbp/chr/CharInput.java b/src/edu/berkeley/sbp/chr/CharInput.java index 65b2b3e..b6a175d 100644 --- a/src/edu/berkeley/sbp/chr/CharInput.java +++ b/src/edu/berkeley/sbp/chr/CharInput.java @@ -48,6 +48,8 @@ public class CharInput extends Cartesian.Input { Cartesian.Region r = (Cartesian.Region)rc; int start = r.getStart().getScalar()+1; int end = r.getEnd().getScalar()+1; + if (start < 0) start = 0; + if (end < start) end = start; if (end > cache.length()) end = cache.length(); String ret; if (end-start < 60) ret = cache.substring(start, end); diff --git a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java index 40f3e39..cae45c0 100644 --- a/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java +++ b/src/edu/berkeley/sbp/meta/MetaGrammarBindings.java @@ -79,9 +79,8 @@ public class MetaGrammarBindings extends AnnotationGrammarBindings { Seq[] group = sequences[i]; Union u2 = new Union(null, false); if (sequences.length==1) u2 = u; - for(int j=0; j" /ws + | GenericTypeDecl:: Identifier "<" (TypeArg +/ comma) ">" /ws TypeArg = Identifier | Extends:: Identifier "extends" Type /ws @@ -43,17 +43,17 @@ MethodDecl = Method:: MethodHeader (";" | MethodBody) /ws MethodHeader = MethodHeader:: Modifiers Type Identifier Args /ws MethodBody = "{" "}" /ws -Args = "(" (Arg+/Comma) ")" /ws +Args = "(" (Arg+/comma) ")" /ws | "(" ws! ")" Arg = Arg:: Type Identifier /ws Type = BareType | GenericType | ArrayType BareType = Type:: TypeName | "boolean" | "int" | "double" | "float" | "char" | "short" | "long" | "void" -GenericType = GenericType:: TypeName "<" (Type+/Comma) ">" /ws +GenericType = GenericType:: TypeName "<" (Type+/comma) ">" /ws ArrayType = ArrayOf:: (BareType | GenericType) "[]" /ws ws = [\r\n ]** -Comma = ws! "," ws! +comma = ws! "," ws! JavaLetter = [a-zA-Z_$] Identifier = JavaLetter++ diff --git a/tests/java15.test b/tests/java15.test index b52f1fa..a8efc19 100644 --- a/tests/java15.test +++ b/tests/java15.test @@ -3,7 +3,7 @@ import foo.bar; public class Baz < A extends Object , Q super Foo,Bop> > { - public void foo(int x, char y, Bop> q) { + public voider adsffbid foo(int x, char y, Bop> q) { } protected abstract int bar(int c);