X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2FParseFailed.java;h=b6a05e0bd3b356b9754629b6ecce77304bf40a20;hp=75baf3af91a02d5fb442ff4791b8f9f9ee7664e7;hb=dc9bb3a45ed306e2e35549076842b3e74efecb48;hpb=6a2ea790f843e058c7e67d3c7d1deebadcfe1fd5 diff --git a/src/edu/berkeley/sbp/ParseFailed.java b/src/edu/berkeley/sbp/ParseFailed.java index 75baf3a..b6a05e0 100644 --- a/src/edu/berkeley/sbp/ParseFailed.java +++ b/src/edu/berkeley/sbp/ParseFailed.java @@ -1,38 +1,131 @@ +// 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.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 { +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, Input.Location loc) { this.location = loc; this.message = message; } + 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; } - public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; } + private Input.Region getRegion() { return region; } + public String toString() { + StringBuilder ret = new StringBuilder(); + ret.append(message); + ret.append('\n'); + return ret.toString(); + } + + private static boolean important(Position p) { + if (p.isLast()) return false; + if (p.element() == null) return false; + if (!(p.element() instanceof Union)) return false; + Union u = (Union)p.element(); + if (u.isSynthetic()) return false; + if (u.getName()==null) return false; + if (u.getName().length() == 0) return false; + char c = u.getName().charAt(0); + return (c >= 'A' && c <= 'Z'); + } + + static void barf(HashMap sb, Node n, int indent, boolean skip, int count, Input.Location loc) { + if (count <= 0) { + barf(sb, n, indent, skip, loc); + } else { + /* + FIXME: removed + for(Node nn : (Iterable)n.parents()) + barf(sb, nn, indent, skip, count-1, n.phase().getLocation()); + */ + } + } + static void barf(HashMap sb, 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 += " "; + Node parent = n; + boolean done = false; + boolean alldone = false; + boolean go = false; + boolean force = false; + for(Position p : (Iterable)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 Cache(null, null).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); + } + + - public static void complain(GSS.Phase.Node n, HashMap> errors, boolean force) { - //if (n.touched) return; - //n.touched = true; - for(Position p : n.state) { - if (((p.isFirst() || p.isLast()) && !force) || p.owner().name==null) { + // FIXME + private static HashSet touched = new HashSet(); + static void complain(Node n, HashMap> errors, boolean force, int indent) { + if (touched.contains(n)) return; + touched.add(n); + for(Position p : (Iterable)n.state()) { + //if (!p.isLast() && !p.next().isLast()) continue; + if (((p.isFirst() || p.isLast()) && !force)/* || p.owner().name==null*/ || + !important(p)) { + /* + FIXME: removed for(Node n2 : n.parents()) - complain(n2, errors, force | p.isFirst()); + complain(n2, errors, force + //| p.isFirst() + , indent); + */ } else { - String seqname = p.owner().name; + 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()+""); } } } - public static String el(Object e) { + 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.substring(1); @@ -44,32 +137,97 @@ public class ParseFailed extends RuntimeException { } return ANSI.purple(ret.toString()); } - public static String error(String message, Object token, Iterable nodes) { + + static void error(String message, GSS.Phase phase) throws ParseFailed { + error(message, phase.getLocation(), phase.getToken(), + phase, phase.getRegion(), phase.getGSS().getInput(), phase.getGSS()); + } + 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, 60); + 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), 60); + 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()); + 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.getEnd()); + ret.append(" to match \"" + ANSI.cyan(input.showRegion(reg, 60)) + "\" 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); } }