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