001:/***************************************************************
002: *
003: ***************************************************************/
004:package com.flexive.sqlParser;
005:
006:/**
007: * Customized token error class.
008: *
009: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
010: */
011:public class TokenMgrError extends Error {
012:
013: private boolean EOFSeen;
014: private int lexState;
015: private int errorLine;
016: private int errorColumn;
017: private String errorAfter;
018: private char curChar;
019:
020: public static enum REASON {
021: LEXICAL_ERROR,
022: STATIC_LEXER_ERROR,
023: INVALID_LEXICAL_STATE,
024: LOOP_DETECTED
025: }
026:
027: /*
028: * Ordinals for various reasons why an Error of this type can be thrown.
029: */
030:
031: /**
032: * Lexical error occured.
033: */
034: static final int LEXICAL_ERROR = 0;
035:
036: /**
037: * An attempt wass made to create a second instance of a static token manager.
038: */
039: static final int STATIC_LEXER_ERROR = 1;
040:
041: /**
042: * Tried to change to an invalid lexical state.
043: */
044: static final int INVALID_LEXICAL_STATE = 2;
045:
046: /**
047: * Detected (and bailed out of) an infinite loop in the token manager.
048: */
049: static final int LOOP_DETECTED = 3;
050:
051: /**
052: * Indicates the reason why the exception is thrown. It will have
053: * one of the above 4 values.
054: */
055: int errorCode;
056:
057: /**
058: * Replaces unprintable characters by their espaced (or unicode escaped)
059: * equivalents in the given string
060: * @param str the string to escape
061: * @return the escape string
062: */
063: protected static String addEscapes(String str) {
064: StringBuffer retval = new StringBuffer();
065: char ch;
066: for (int i = 0; i < str.length(); i++) {
067: switch (str.charAt(i))
068: {
069: case 0 :
070: continue;
071: case '\b':
072: retval.append("\\b");
073: continue;
074: case '\t':
075: retval.append("\\t");
076: continue;
077: case '\n':
078: retval.append("\\n");
079: continue;
080: case '\f':
081: retval.append("\\f");
082: continue;
083: case '\r':
084: retval.append("\\r");
085: continue;
086: case '\"':
087: retval.append("\\\"");
088: continue;
089: case '\'':
090: retval.append("\\\'");
091: continue;
092: case '\\':
093: retval.append("\\\\");
094: continue;
095: default:
096: if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
097: String s = "0000" + Integer.toString(ch, 16);
098: retval.append("\\u").append(s.substring(s.length() - 4, s.length()));
099: } else {
100: retval.append(ch);
101: }
102: }
103: }
104: return retval.toString();
105: }
106:
107:
108: /**
109: * Returns a detailed message for the Error when it is thrown by the
110: * token manager to indicate a lexical error.
111: *
112: * @param EOFSeen indicates if EOF caused the lexicl error
113: * @param lexState lexical state in which this error occured
114: * @param errorLine line number when the error occured
115: * @param errorColumn column number when the error occured
116: * @param errorAfter prefix that was seen before this error occured
117: * @param curChar the offending character
118: * @return the string
119: */
120: protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
121: return("Lexical error at line " +
122: errorLine + ", column " +
123: errorColumn + ". Encountered: " +
124: (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
125: "after : \"" + addEscapes(errorAfter) + "\"");
126: }
127:
128:
129: /**
130: * Empty constructor
131: */
132: public TokenMgrError() {
133: }
134:
135: /**
136: * Constructor.
137: *
138: * @param message the message
139: * @param reason the reason
140: */
141: public TokenMgrError(String message, int reason) {
142: super (message);
143: errorCode = reason;
144: }
145:
146: /**
147: * Constructor.
148: *
149: * @param EOFSeen indicates if EOF caused the lexicl error
150: * @param lexState lexical state in which this error occured
151: * @param errorLine line number when the error occured
152: * @param errorColumn column number when the error occured
153: * @param errorAfter prefix that was seen before this error occured
154: * @param curChar the offending character
155: * @param reason the reason
156: */
157: public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
158: this (LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
159: this .EOFSeen=EOFSeen;
160: this .lexState=lexState;
161: this .errorLine=errorLine;
162: this .errorColumn=errorColumn;
163: this .errorAfter=errorAfter;
164: this .curChar=curChar;
165: this .errorCode=reason;
166: }
167:
168: /**
169: * indicates if EOF caused the lexicl error
170: *
171: * @return true or false
172: */
173: public boolean getEofSeen() {
174: return EOFSeen;
175: }
176:
177: /**
178: * lexical state in which this error occured.
179: *
180: * @return lexical state in which this error occured
181: */
182: public int getLexState() {
183: return lexState;
184: }
185:
186: /**
187: * line number when the error occured
188: *
189: * @return line number when the error occured
190: */
191: public int getErrorLine() {
192: return errorLine;
193: }
194:
195: /**
196: * column number when the error occured
197: *
198: * @return column number when the error occured
199: */
200: public int getErrorColumn() {
201: return errorColumn;
202: }
203:
204:
205: /**
206: * prefix that was seen before this error occured
207: *
208: * @return prefix that was seen before this error occured
209: */
210: public String getErrorAfter() {
211: return errorAfter;
212: }
213:
214: /**
215: * the offending character
216: *
217: * @return the offending character
218: */
219: public char getCurChar() {
220: return curChar;
221: }
222:
223: /**
224: * The offending character as escaped String.
225: * <p />
226: * The function replaces unprintable characters by their espaced (or unicode escaped)
227: * equivalents in the given string
228: *
229: * @return the offending character
230: */
231: public String getCurCharEscaped() {
232: return addEscapes(String.valueOf(curChar));
233: }
234:
235:
236: /**
237: * Returns the error reason.
238: *
239: * @return the error reason
240: */
241: public REASON getReason() {
242: switch(this.errorCode) {
243: case LEXICAL_ERROR:
244: return REASON.LEXICAL_ERROR;
245: case STATIC_LEXER_ERROR:
246: return REASON.STATIC_LEXER_ERROR;
247: case INVALID_LEXICAL_STATE:
248: return REASON.INVALID_LEXICAL_STATE;
249: case LOOP_DETECTED:
250: return REASON.LOOP_DETECTED;
251: default:
252: return REASON.LEXICAL_ERROR;
253: }
254: }
255:}
|