checkpoint
[sbp.git] / src / edu / berkeley / sbp / ParseFailed.java
1 package edu.berkeley.sbp;
2 import edu.berkeley.sbp.*;
3 import edu.berkeley.sbp.Sequence.Position;
4 import edu.berkeley.sbp.GSS.Phase;
5 import edu.berkeley.sbp.GSS.Phase.Node;
6 import edu.berkeley.sbp.util.*;
7 import java.io.*;
8 import java.util.*;
9
10 /** thrown when the parser arrives at a state from which it is clear that no valid parse can result */
11 public class ParseFailed extends RuntimeException {
12     private final Input.Location location;
13     private final String message;
14     public ParseFailed() { this("", null); }
15     public ParseFailed(String message, Input.Location loc) { this.location = loc; this.message = message; }
16     public Input.Location getLocation() { return location; }
17     public String toString() { return message/* + (location==null ? "" : (" at " + location))*/; }
18
19     public static <Tok> void complain(GSS.Phase<Tok>.Node n, HashMap<String,HashSet<String>> errors, boolean force) {
20         //if (n.touched) return;
21         //n.touched = true;
22         for(Position p : n.state) {
23             if (((p.isFirst() || p.isLast()) && !force) || p.owner().name==null) {
24                 for(Node n2 : n.parents())
25                     complain(n2, errors, force | p.isFirst());
26             } else {
27                 String seqname = p.owner().name;
28                 HashSet<String> hs = errors.get(seqname);
29                 if (hs==null) errors.put(seqname, hs = new HashSet<String>());
30                 hs.add(p.element()+"");
31             }
32         }
33     }
34
35     public static String el(Object e) {
36         String s = e.toString();
37         if (s.length()==0 || s.charAt(0)!='\"' || s.charAt(s.length()-1)!='\"') return ANSI.yellow(s);
38         s = s.substring(1);
39         s = s.substring(0, s.length()-1);
40         StringBuffer ret = new StringBuffer();
41         for(int i=0; i<s.length(); i++) {
42             if (s.charAt(i)=='\\' && i<s.length()-1) ret.append(s.charAt(++i));
43             else ret.append(s);
44         }
45         return ANSI.purple(ret.toString());
46     }
47     public static String error(String message, Object token, Iterable<Node> nodes) {
48         String lookAhead = token==null ? "<EOF>" : token.toString();
49         StringBuffer ret = new StringBuffer();
50         ret.append("\n  ");
51         ret.append(message);
52         HashMap<String,HashSet<String>> errors = new HashMap<String,HashSet<String>>();
53         for(Node n : nodes) {
54             //System.out.println(n.state);
55             complain(n, errors, false);
56         }
57         for(String s : errors.keySet()) {
58             ret.append("    while parsing " + ANSI.yellow(s));
59             HashSet<String> hs = errors.get(s);
60             if (hs.size()==1) ret.append(" expected " + ANSI.yellow(el(hs.iterator().next())) + "\n");
61             else {
62                 ret.append(" expected ");
63                 boolean first = true;
64                 for(String s2 : hs) {
65                     if (!first) ret.append(" or ");
66                     first = false;
67                     ret.append(ANSI.yellow(el(s2)));
68                 }
69                 ret.append("\n");
70             }
71         }
72         return ret.toString();
73     }
74
75 }