checkpoint
[sbp.git] / src / edu / berkeley / sbp / ParseFailed.java
1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
2
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.*;
9 import java.io.*;
10 import java.util.*;
11
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 {
14
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) {
21         this.region = region;
22         this.location = region.getStart();
23         this.message = message;
24         this.input = input;
25     }
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();
34         ret.append(message);
35         ret.append('\n');
36         ret.append("      at: ");
37         ret.append(getRegion()+"");
38         if (input != null) {
39             ret.append('\n');
40             ret.append("    text: ");
41             String first = input.showRegion(before.createRegion(getRegion().getStart()));
42             ret.append(first);
43             String second = input.showRegion(getRegion());
44             ret.append(ANSI.red(second));
45             ret.append(input.showRegion(getRegion().getEnd().createRegion(after)));
46             ret.append('\n');
47             ret.append("          ");
48             for(int i=0; i<first.length(); i++) ret.append(' ');
49             for(int i=0; i<second.length(); i++) ret.append(ANSI.red("^"));
50         }
51         return ret.toString();
52     }
53
54     // FIXME
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;
58         touched.add(n);
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());
63             } else {
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()+"");
68             }
69         }
70     }
71
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;
75         s = s.substring(1);
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));
80             else ret.append(s);
81         }
82         return /*ANSI.purple(ret.toString())*/ret.toString();
83     }
84     static String error(String message, Object token, Iterable<Node> nodes) {
85         String lookAhead = token==null ? "<EOF>" : token.toString();
86         StringBuffer ret = new StringBuffer();
87         ret.append("\n  ");
88         ret.append(message);
89         /*
90         HashMap<String,HashSet<String>> errors = new HashMap<String,HashSet<String>>();
91         for(Node n : nodes) {
92             //System.out.println(n.state);
93             complain(n, errors, false);
94         }
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");
99             else {
100                 ret.append(" expected ");
101                 boolean first = true;
102                 for(String s2 : hs) {
103                     if (!first) ret.append(" or ");
104                     first = false;
105                     ret.append(ANSI.yellow(el(s2)));
106                 }
107                 ret.append("\n");
108             }
109         }
110         */
111         return ret.toString();
112     }
113
114 }