001 /* Generated By:JavaCC: Do not edit this line. ParseException.java Version 4.1 */
002 /* JavaCCOptions:KEEP_LINE_COL=null */
003 /*
004 * Copyright (c) 2009 The JOMC Project
005 * Copyright (c) 2005 Christian Schulte <cs@jomc.org>
006 * All rights reserved.
007 *
008 * Redistribution and use in source and binary forms, with or without
009 * modification, are permitted provided that the following conditions
010 * are met:
011 *
012 * o Redistributions of source code must retain the above copyright
013 * notice, this list of conditions and the following disclaimer.
014 *
015 * o Redistributions in binary form must reproduce the above copyright
016 * notice, this list of conditions and the following disclaimer in
017 * the documentation and/or other materials provided with the
018 * distribution.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
029 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
030 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 *
032 * $Id: VersionParser.jj 573 2009-09-25 16:05:05Z schulte2005 $
033 *
034 */
035 package org.jomc.util;
036
037 /**
038 * This exception is thrown when parse errors are encountered.
039 * You can explicitly create objects of this exception type by
040 * calling the method generateParseException in the generated
041 * parser.
042 *
043 * You can modify this class to customize your error reporting
044 * mechanisms so long as you retain the public fields.
045 */
046 public class ParseException extends Exception {
047
048 /**
049 * This constructor is used by the method "generateParseException"
050 * in the generated parser. Calling this constructor generates
051 * a new object of this type with the fields "currentToken",
052 * "expectedTokenSequences", and "tokenImage" set. The boolean
053 * flag "specialConstructor" is also set to true to indicate that
054 * this constructor was used to create this object.
055 * This constructor calls its super class with the empty string
056 * to force the "toString" method of parent class "Throwable" to
057 * print the error message in the form:
058 * ParseException: <result of getMessage>
059 */
060 public ParseException(Token currentTokenVal,
061 int[][] expectedTokenSequencesVal,
062 String[] tokenImageVal
063 )
064 {
065 super("");
066 specialConstructor = true;
067 currentToken = currentTokenVal;
068 expectedTokenSequences = expectedTokenSequencesVal;
069 tokenImage = tokenImageVal;
070 }
071
072 /**
073 * The following constructors are for use by you for whatever
074 * purpose you can think of. Constructing the exception in this
075 * manner makes the exception behave in the normal way - i.e., as
076 * documented in the class "Throwable". The fields "errorToken",
077 * "expectedTokenSequences", and "tokenImage" do not contain
078 * relevant information. The JavaCC generated code does not use
079 * these constructors.
080 */
081
082 public ParseException() {
083 super();
084 specialConstructor = false;
085 }
086
087 /** Constructor with message. */
088 public ParseException(String message) {
089 super(message);
090 specialConstructor = false;
091 }
092
093 /**
094 * This variable determines which constructor was used to create
095 * this object and thereby affects the semantics of the
096 * "getMessage" method (see below).
097 */
098 protected boolean specialConstructor;
099
100 /**
101 * This is the last token that has been consumed successfully. If
102 * this object has been created due to a parse error, the token
103 * followng this token will (therefore) be the first error token.
104 */
105 public Token currentToken;
106
107 /**
108 * Each entry in this array is an array of integers. Each array
109 * of integers represents a sequence of tokens (by their ordinal
110 * values) that is expected at this point of the parse.
111 */
112 public int[][] expectedTokenSequences;
113
114 /**
115 * This is a reference to the "tokenImage" array of the generated
116 * parser within which the parse error occurred. This array is
117 * defined in the generated ...Constants interface.
118 */
119 public String[] tokenImage;
120
121 /**
122 * This method has the standard behavior when this object has been
123 * created using the standard constructors. Otherwise, it uses
124 * "currentToken" and "expectedTokenSequences" to generate a parse
125 * error message and returns it. If this object has been created
126 * due to a parse error, and you do not catch it (it gets thrown
127 * from the parser), then this method is called during the printing
128 * of the final stack trace, and hence the correct error message
129 * gets displayed.
130 */
131 public String getMessage() {
132 if (!specialConstructor) {
133 return super.getMessage();
134 }
135 StringBuffer expected = new StringBuffer();
136 int maxSize = 0;
137 for (int i = 0; i < expectedTokenSequences.length; i++) {
138 if (maxSize < expectedTokenSequences[i].length) {
139 maxSize = expectedTokenSequences[i].length;
140 }
141 for (int j = 0; j < expectedTokenSequences[i].length; j++) {
142 expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
143 }
144 if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
145 expected.append("...");
146 }
147 expected.append(eol).append(" ");
148 }
149 String retval = "Encountered \"";
150 Token tok = currentToken.next;
151 for (int i = 0; i < maxSize; i++) {
152 if (i != 0) retval += " ";
153 if (tok.kind == 0) {
154 retval += tokenImage[0];
155 break;
156 }
157 retval += " " + tokenImage[tok.kind];
158 retval += " \"";
159 retval += add_escapes(tok.image);
160 retval += " \"";
161 tok = tok.next;
162 }
163 retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
164 retval += "." + eol;
165 if (expectedTokenSequences.length == 1) {
166 retval += "Was expecting:" + eol + " ";
167 } else {
168 retval += "Was expecting one of:" + eol + " ";
169 }
170 retval += expected.toString();
171 return retval;
172 }
173
174 /**
175 * The end of line string for this machine.
176 */
177 protected String eol = System.getProperty("line.separator", "\n");
178
179 /**
180 * Used to convert raw characters to their escaped version
181 * when these raw version cannot be used as part of an ASCII
182 * string literal.
183 */
184 protected String add_escapes(String str) {
185 StringBuffer retval = new StringBuffer();
186 char ch;
187 for (int i = 0; i < str.length(); i++) {
188 switch (str.charAt(i))
189 {
190 case 0 :
191 continue;
192 case '\b':
193 retval.append("\\b");
194 continue;
195 case '\t':
196 retval.append("\\t");
197 continue;
198 case '\n':
199 retval.append("\\n");
200 continue;
201 case '\f':
202 retval.append("\\f");
203 continue;
204 case '\r':
205 retval.append("\\r");
206 continue;
207 case '\"':
208 retval.append("\\\"");
209 continue;
210 case '\'':
211 retval.append("\\\'");
212 continue;
213 case '\\':
214 retval.append("\\\\");
215 continue;
216 default:
217 if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
218 String s = "0000" + Integer.toString(ch, 16);
219 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
220 } else {
221 retval.append(ch);
222 }
223 continue;
224 }
225 }
226 return retval.toString();
227 }
228
229 }
230 /* JavaCC - OriginalChecksum=d65c88db54d0cd91c450423e107d8f30 (do not edit this line) */