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