001: /*
002: * ParserCreationException.java
003: *
004: * This work is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published
006: * by the Free Software Foundation; either version 2 of the License,
007: * or (at your option) any later version.
008: *
009: * This work is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017: * USA
018: *
019: * As a special exception, the copyright holders of this library give
020: * you permission to link this library with independent modules to
021: * produce an executable, regardless of the license terms of these
022: * independent modules, and to copy and distribute the resulting
023: * executable under terms of your choice, provided that you also meet,
024: * for each linked independent module, the terms and conditions of the
025: * license of that module. An independent module is a module which is
026: * not derived from or based on this library. If you modify this
027: * library, you may extend this exception to your version of the
028: * library, but you are not obligated to do so. If you do not wish to
029: * do so, delete this exception statement from your version.
030: *
031: * Copyright (c) 2003 Per Cederberg. All rights reserved.
032: */
033:
034: package net.percederberg.grammatica.parser;
035:
036: import java.util.ArrayList;
037:
038: /**
039: * A parser creation exception. This exception is used for signalling
040: * an error in the token or production patterns, making it impossible
041: * to create a working parser or tokenizer.
042: *
043: * @author Per Cederberg, <per at percederberg dot net>
044: * @version 1.0
045: */
046: public class ParserCreationException extends Exception {
047:
048: /**
049: * The internal error type constant. This type is only used to
050: * signal an error that is a result of a bug in the parser or
051: * tokenizer code.
052: */
053: public static final int INTERNAL_ERROR = 0;
054:
055: /**
056: * The invalid parser error type constant. This type is used when
057: * the parser as such is invalid. This error is typically caused
058: * by using a parser without any patterns.
059: */
060: public static final int INVALID_PARSER_ERROR = 1;
061:
062: /**
063: * The invalid token error type constant. This type is used when a
064: * token pattern is erroneous. This error is typically caused by
065: * an invalid pattern type or an erroneous regular expression.
066: */
067: public static final int INVALID_TOKEN_ERROR = 2;
068:
069: /**
070: * The invalid production error type constant. This type is used
071: * when a production pattern is erroneous. This error is typically
072: * caused by referencing undeclared productions, or violating some
073: * other production pattern constraint.
074: */
075: public static final int INVALID_PRODUCTION_ERROR = 3;
076:
077: /**
078: * The infinite loop error type constant. This type is used when
079: * an infinite loop has been detected in the grammar. One of the
080: * productions in the loop will be reported.
081: */
082: public static final int INFINITE_LOOP_ERROR = 4;
083:
084: /**
085: * The inherent ambiguity error type constant. This type is used
086: * when the set of production patterns (i.e. the grammar) contains
087: * ambiguities that cannot be resolved.
088: */
089: public static final int INHERENT_AMBIGUITY_ERROR = 5;
090:
091: /**
092: * The error type.
093: */
094: private int type;
095:
096: /**
097: * The token or production pattern name. This variable is only
098: * set for some error types.
099: */
100: private String name;
101:
102: /**
103: * The additional error information string. This variable is only
104: * set for some error types.
105: */
106: private String info;
107:
108: /**
109: * The error details list. This variable is only set for some
110: * error types.
111: */
112: private ArrayList details;
113:
114: /**
115: * Creates a new parser creation exception.
116: *
117: * @param type the parse error type
118: * @param info the additional error information
119: */
120: public ParserCreationException(int type, String info) {
121:
122: this (type, null, info);
123: }
124:
125: /**
126: * Creates a new parser creation exception.
127: *
128: * @param type the parse error type
129: * @param name the token or production pattern name
130: * @param info the additional error information
131: */
132: public ParserCreationException(int type, String name, String info) {
133:
134: this (type, name, info, null);
135: }
136:
137: /**
138: * Creates a new parser creation exception.
139: *
140: * @param type the parse error type
141: * @param name the token or production pattern name
142: * @param info the additional error information
143: * @param details the error details list
144: */
145: public ParserCreationException(int type, String name, String info,
146: ArrayList details) {
147:
148: this .type = type;
149: this .name = name;
150: this .info = info;
151: this .details = details;
152: }
153:
154: /**
155: * Returns the error type.
156: *
157: * @return the error type
158: */
159: public int getErrorType() {
160: return type;
161: }
162:
163: /**
164: * Returns the token or production name.
165: *
166: * @return the token or production name
167: */
168: public String getName() {
169: return name;
170: }
171:
172: /**
173: * Returns the additional error information.
174: *
175: * @return the additional error information
176: */
177: public String getInfo() {
178: return info;
179: }
180:
181: /**
182: * Returns the detailed error information as a string
183: *
184: * @return the detailed error information
185: */
186: public String getDetails() {
187: StringBuffer buffer = new StringBuffer();
188:
189: if (details == null) {
190: return null;
191: }
192: for (int i = 0; i < details.size(); i++) {
193: if (i > 0) {
194: buffer.append(", ");
195: if (i + 1 == details.size()) {
196: buffer.append("and ");
197: }
198: }
199: buffer.append(details.get(i));
200: }
201:
202: return buffer.toString();
203: }
204:
205: /**
206: * Returns the error message. This message will contain all the
207: * information available.
208: *
209: * @return the error message
210: */
211: public String getMessage() {
212: StringBuffer buffer = new StringBuffer();
213:
214: switch (type) {
215: case INVALID_PARSER_ERROR:
216: buffer.append("parser is invalid, as ");
217: buffer.append(info);
218: break;
219: case INVALID_TOKEN_ERROR:
220: buffer.append("token '");
221: buffer.append(name);
222: buffer.append("' is invalid, as ");
223: buffer.append(info);
224: break;
225: case INVALID_PRODUCTION_ERROR:
226: buffer.append("production '");
227: buffer.append(name);
228: buffer.append("' is invalid, as ");
229: buffer.append(info);
230: break;
231: case INFINITE_LOOP_ERROR:
232: buffer
233: .append("infinite loop found in production pattern '");
234: buffer.append(name);
235: buffer.append("'");
236: break;
237: case INHERENT_AMBIGUITY_ERROR:
238: buffer.append("inherent ambiguity in production '");
239: buffer.append(name);
240: buffer.append("'");
241: if (info != null) {
242: buffer.append(" ");
243: buffer.append(info);
244: }
245: if (details != null) {
246: buffer.append(" starting with ");
247: if (details.size() > 1) {
248: buffer.append("tokens ");
249: } else {
250: buffer.append("token ");
251: }
252: buffer.append(getDetails());
253: }
254: break;
255: default:
256: buffer.append("internal error");
257: }
258:
259: return buffer.toString();
260: }
261: }
|