1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
3 package edu.berkeley.sbp;
4 import edu.berkeley.sbp.*;
5 import edu.berkeley.sbp.Sequence.Position;
6 import edu.berkeley.sbp.GSS.Phase;
7 import edu.berkeley.sbp.GSS.Phase.Node;
8 import edu.berkeley.sbp.util.*;
12 /** thrown when the parser arrives at a state from which it is clear that no valid parse can result */
13 public class ParseFailed extends Exception {
15 private final Input.Location location;
16 private final Input.Region region;
17 private final Input input;
18 private final String message;
19 ParseFailed() { this("", null, null); }
20 ParseFailed(String message, Input.Region region, Input input) {
22 this.location = region.getStart();
23 this.message = message;
26 public Input.Location getLocation() { return location; }
27 private Input.Region getRegion() { return region; }
28 public String toString() {
29 Input.Location before = getRegion().getStart();
30 for(int i=0; i<10; i++) before = before.prev() == null ? before : before.prev();
31 Input.Location after = getRegion().getEnd();
32 for(int i=0; i<10; i++) after = after.next() == null ? after : after.next();
33 StringBuilder ret = new StringBuilder();
37 ret.append(getRegion()+"");
40 ret.append(" text: ");
41 String first = input.showRegion(before.createRegion(getRegion().getStart()));
43 String second = input.showRegion(getRegion());
44 ret.append(ANSI.red(second));
45 ret.append(input.showRegion(getRegion().getEnd().createRegion(after)));
48 for(int i=0; i<first.length(); i++) ret.append(' ');
49 for(int i=0; i<second.length(); i++) ret.append(ANSI.red("^"));
51 return ret.toString();
55 private static HashSet<GSS.Phase.Node> touched = new HashSet<GSS.Phase.Node>();
56 static <Tok> void complain(GSS.Phase<Tok>.Node n, HashMap<String,HashSet<String>> errors, boolean force) {
57 if (touched.contains(n)) return;
59 for(Position p : n.state) {
60 if (((p.isFirst() || p.isLast()) && !force)/* || p.owner().name==null*/) {
61 for(Node n2 : n.parents())
62 complain(n2, errors, force | p.isFirst());
64 String seqname = p.owner()/*.name*/+"";
65 HashSet<String> hs = errors.get(seqname);
66 if (hs==null) errors.put(seqname, hs = new HashSet<String>());
67 hs.add(p.element()+"");
72 static String el(Object e) {
73 String s = e.toString();
74 if (s.length()==0 || s.charAt(0)!='\"' || s.charAt(s.length()-1)!='\"') return /*ANSI.yellow(s)*/s;
76 s = s.substring(0, s.length()-1);
77 StringBuffer ret = new StringBuffer();
78 for(int i=0; i<s.length(); i++) {
79 if (s.charAt(i)=='\\' && i<s.length()-1) ret.append(s.charAt(++i));
82 return /*ANSI.purple(ret.toString())*/ret.toString();
84 static String error(String message, Object token, Iterable<Node> nodes) {
85 String lookAhead = token==null ? "<EOF>" : token.toString();
86 StringBuffer ret = new StringBuffer();
90 HashMap<String,HashSet<String>> errors = new HashMap<String,HashSet<String>>();
92 //System.out.println(n.state);
93 complain(n, errors, false);
95 for(String s : errors.keySet()) {
96 ret.append(" while parsing " + ANSI.yellow(s));
97 HashSet<String> hs = errors.get(s);
98 if (hs.size()==1) ret.append(" expected " + ANSI.yellow(el(hs.iterator().next())) + "\n");
100 ret.append(" expected ");
101 boolean first = true;
102 for(String s2 : hs) {
103 if (!first) ret.append(" or ");
105 ret.append(ANSI.yellow(el(s2)));
111 return ret.toString();