001: /*
002: * Author: Mike Atkinson
003: *
004: * This software has been developed under the copyleft
005: * rules of the GNU General Public License. Please
006: * consult the GNU General Public License for more
007: * details about use and distribution of this software.
008: */
009: package net.sourceforge.jrefactory.parser;
010:
011: /*
012: * Generated By:JavaCC: Do not edit this line. ParseException.java Version 0.7pre6
013: */
014: /**
015: * This exception is thrown when parse errors are encountered. You can
016: * explicitly create objects of this exception type by calling the method
017: * generateParseException in the generated parser. You can modify this class to
018: * customize your error reporting mechanisms so long as you retain the public
019: * fields.
020: *
021: *@author Mike Atkinson
022: *@created October 14, 1999
023: */
024: public class ParseException extends Exception {
025:
026: /**
027: * This is the last token that has been consumed successfully. If this
028: * object has been created due to a parse error, the token followng this
029: * token will (therefore) be the first error token.
030: */
031: public Token currentToken;
032:
033: /**
034: * Each entry in this array is an array of integers. Each array of integers
035: * represents a sequence of tokens (by their ordinal values) that is
036: * expected at this point of the parse.
037: */
038: public int[][] expectedTokenSequences;
039:
040: /**
041: * This is a reference to the "tokenImage" array of the generated parser
042: * within which the parse error occurred. This array is defined in the
043: * generated ...Constants interface.
044: */
045: public String[] tokenImage;
046:
047: /**
048: * The end of line string for this machine.
049: */
050: protected String eol = System.getProperty("line.separator", "\n");
051:
052: /**
053: * This variable determines which constructor was used to create this
054: * object and thereby affects the semantics of the "getMessage" method (see
055: * below).
056: */
057: protected boolean specialConstructor;
058:
059: /**
060: * This constructor is used by the method "generateParseException" in the
061: * generated parser. Calling this constructor generates a new object of
062: * this type with the fields "currentToken", "expectedTokenSequences", and
063: * "tokenImage" set. The boolean flag "specialConstructor" is also set to
064: * true to indicate that this constructor was used to create this object.
065: * This constructor calls its super class with the empty string to force
066: * the "toString" method of parent class "Throwable" to print the error
067: * message in the form: ParseException: <result of getMessage>
068: *
069: *@param currentTokenVal Description of Parameter
070: *@param expectedTokenSequencesVal Description of Parameter
071: *@param tokenImageVal Description of Parameter
072: */
073: public ParseException(Token currentTokenVal,
074: int[][] expectedTokenSequencesVal, String[] tokenImageVal) {
075: super ("");
076: specialConstructor = true;
077: currentToken = currentTokenVal;
078: expectedTokenSequences = expectedTokenSequencesVal;
079: tokenImage = tokenImageVal;
080: }
081:
082: /**
083: * The following constructors are for use by you for whatever purpose you
084: * can think of. Constructing the exception in this manner makes the
085: * exception behave in the normal way - i.e., as documented in the class
086: * "Throwable". The fields "errorToken", "expectedTokenSequences", and
087: * "tokenImage" do not contain relevant information. The JavaCC generated
088: * code does not use these constructors.
089: */
090:
091: public ParseException() {
092: super ();
093: specialConstructor = false;
094: }
095:
096: /**
097: * Constructor for the ParseException object
098: *
099: *@param message Description of Parameter
100: */
101: public ParseException(String message) {
102: super (message);
103: specialConstructor = false;
104: }
105:
106: /**
107: * This method has the standard behavior when this object has been created
108: * using the standard constructors. Otherwise, it uses "currentToken" and
109: * "expectedTokenSequences" to generate a parse error message and returns
110: * it. If this object has been created due to a parse error, and you do not
111: * catch it (it gets thrown from the parser), then this method is called
112: * during the printing of the final stack trace, and hence the correct
113: * error message gets displayed.
114: *
115: *@return Description of the Returned Value
116: */
117: public String getMessage() {
118: if (!specialConstructor) {
119: return super .getMessage();
120: }
121: String expected = "";
122: int maxSize = 0;
123: for (int i = 0; i < expectedTokenSequences.length; i++) {
124: if (maxSize < expectedTokenSequences[i].length) {
125: maxSize = expectedTokenSequences[i].length;
126: }
127: for (int j = 0; j < expectedTokenSequences[i].length; j++) {
128: expected += tokenImage[expectedTokenSequences[i][j]]
129: + " ";
130: }
131: if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
132: expected += "...";
133: }
134: expected += eol + " ";
135: }
136: String retval = "Encountered \"";
137: Token tok = currentToken.next;
138: for (int i = 0; i < maxSize; i++) {
139: if (i != 0) {
140: retval += " ";
141: }
142: if (tok.kind == 0) {
143: retval += tokenImage[0];
144: break;
145: }
146: retval += add_escapes(tok.image);
147: tok = tok.next;
148: }
149: retval += "\" at line " + currentToken.next.beginLine
150: + ", column " + currentToken.next.beginColumn + "."
151: + eol;
152: if (expectedTokenSequences.length == 1) {
153: retval += "Was expecting:" + eol + " ";
154: } else {
155: retval += "Was expecting one of:" + eol + " ";
156: }
157: retval += expected;
158: return retval;
159: }
160:
161: /**
162: * Used to convert raw characters to their escaped version when these raw
163: * version cannot be used as part of an ASCII string literal.
164: *
165: *@param str Description of Parameter
166: *@return Description of the Returned Value
167: */
168: protected String add_escapes(String str) {
169: StringBuffer retval = new StringBuffer();
170: char ch;
171: for (int i = 0; i < str.length(); i++) {
172: switch (str.charAt(i)) {
173: case 0:
174: continue;
175: case '\b':
176: retval.append("\\b");
177: continue;
178: case '\t':
179: retval.append("\\t");
180: continue;
181: case '\n':
182: retval.append("\\n");
183: continue;
184: case '\f':
185: retval.append("\\f");
186: continue;
187: case '\r':
188: retval.append("\\r");
189: continue;
190: case '\"':
191: retval.append("\\\"");
192: continue;
193: case '\'':
194: retval.append("\\\'");
195: continue;
196: case '\\':
197: retval.append("\\\\");
198: continue;
199: default:
200: if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
201: String s = "0000" + Integer.toString(ch, 16);
202: retval.append("\\u"
203: + s.substring(s.length() - 4, s.length()));
204: } else {
205: retval.append(ch);
206: }
207: continue;
208: }
209: }
210: return retval.toString();
211: }
212:
213: }
|