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