001: /*
002: * TokenPattern.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: /**
037: * A token pattern. This class contains the definition of a token
038: * (i.e. it's pattern), and allows testing a string against this
039: * pattern. A token pattern is uniquely identified by an integer id,
040: * that must be provided upon creation.
041: *
042: * @author Per Cederberg, <per at percederberg dot net>
043: * @version 1.1
044: */
045: public class TokenPattern {
046:
047: /**
048: * The string pattern type. This pattern type is used for tokens
049: * that only match an exact string.
050: */
051: public static final int STRING_TYPE = 1;
052:
053: /**
054: * The regular expression pattern type. This pattern type is used
055: * for tokens that match a regular expression.
056: */
057: public static final int REGEXP_TYPE = 2;
058:
059: /**
060: * The token pattern identity.
061: */
062: private int id;
063:
064: /**
065: * The token pattern name.
066: */
067: private String name;
068:
069: /**
070: * The token pattern type.
071: */
072: private int type;
073:
074: /**
075: * The token pattern.
076: */
077: private String pattern;
078:
079: /**
080: * The token error flag. If this flag is set, it means that an
081: * error should be reported if the token is found. The error
082: * message is present in the errorMessage variable.
083: *
084: * @see #errorMessage
085: */
086: private boolean error = false;
087:
088: /**
089: * The token error message. This message will only be set if the
090: * token error flag is set.
091: *
092: * @see #error
093: */
094: private String errorMessage = null;
095:
096: /**
097: * The token ignore flag. If this flag is set, it means that the
098: * token should be ignored if found. If an ignore message is
099: * present in the ignoreMessage variable, it will also be reported
100: * as a warning.
101: *
102: * @see #ignoreMessage
103: */
104: private boolean ignore = false;
105:
106: /**
107: * The token ignore message. If this message is set when the token
108: * ignore flag is also set, a warning message will be printed if
109: * the token is found.
110: *
111: * @see #ignore
112: */
113: private String ignoreMessage = null;
114:
115: /**
116: * Creates a new token pattern.
117: *
118: * @param id the token pattern id
119: * @param name the token pattern name
120: * @param type the token pattern type
121: * @param pattern the token pattern
122: */
123: public TokenPattern(int id, String name, int type, String pattern) {
124:
125: this .id = id;
126: this .name = name;
127: this .type = type;
128: this .pattern = pattern;
129: }
130:
131: /**
132: * Checks if the pattern corresponds to an error token. If this
133: * is true, it means that an error should be reported if a
134: * matching token is found.
135: *
136: * @return true if the pattern maps to an error token, or
137: * false otherwise
138: */
139: public boolean isError() {
140: return error;
141: }
142:
143: /**
144: * Checks if the pattern corresponds to an ignored token. If this
145: * is true, it means that the token should be ignored if found.
146: *
147: * @return true if the pattern maps to an ignored token, or
148: * false otherwise
149: */
150: public boolean isIgnore() {
151: return ignore;
152: }
153:
154: /**
155: * Returns the unique token pattern identity value.
156: *
157: * @return the token pattern id
158: */
159: public int getId() {
160: return id;
161: }
162:
163: /**
164: * Returns the token pattern name.
165: *
166: * @return the token pattern name
167: */
168: public String getName() {
169: return name;
170: }
171:
172: /**
173: * Returns the token pattern type.
174: *
175: * @return the token pattern type
176: *
177: * @see #STRING_TYPE
178: * @see #REGEXP_TYPE
179: */
180: public int getType() {
181: return type;
182: }
183:
184: /**
185: * Returns te token pattern.
186: *
187: * @return the token pattern
188: */
189: public String getPattern() {
190: return pattern;
191: }
192:
193: /**
194: * Returns the token error message if the pattern corresponds to
195: * an error token.
196: *
197: * @return the token error message
198: */
199: public String getErrorMessage() {
200: return errorMessage;
201: }
202:
203: /**
204: * Returns the token ignore message if the pattern corresponds to
205: * an ignored token.
206: *
207: * @return the token ignore message
208: */
209: public String getIgnoreMessage() {
210: return ignoreMessage;
211: }
212:
213: /**
214: * Sets the token error flag and assigns a default error message.
215: */
216: public void setError() {
217: setError("unrecognized token found");
218: }
219:
220: /**
221: * Sets the token error flag and assigns the specified error
222: * message.
223: *
224: * @param message the error message to display
225: */
226: public void setError(String message) {
227: error = true;
228: errorMessage = message;
229: }
230:
231: /**
232: * Sets the token ignore flag and clears the ignore message.
233: */
234: public void setIgnore() {
235: setIgnore(null);
236: }
237:
238: /**
239: * Sets the token ignore flag and assigns the specified ignore
240: * message.
241: *
242: * @param message the ignore message to display
243: */
244: public void setIgnore(String message) {
245: ignore = true;
246: ignoreMessage = message;
247: }
248:
249: /**
250: * Returns a detailed string representation of this object.
251: *
252: * @return a detailed string representation of this object
253: */
254: public String toString() {
255: StringBuffer buffer = new StringBuffer();
256:
257: buffer.append(name);
258: buffer.append(" (");
259: buffer.append(id);
260: buffer.append(") = ");
261: if (type == STRING_TYPE) {
262: buffer.append("\"");
263: buffer.append(pattern);
264: buffer.append("\"");
265: } else if (type == REGEXP_TYPE) {
266: buffer.append("<<");
267: buffer.append(pattern);
268: buffer.append(">>");
269: }
270: if (error) {
271: buffer.append(" ERROR: \"");
272: buffer.append(errorMessage);
273: buffer.append("\"");
274: }
275: if (ignore) {
276: buffer.append(" IGNORE");
277: if (ignoreMessage != null) {
278: buffer.append(": \"");
279: buffer.append(ignoreMessage);
280: buffer.append("\"");
281: }
282: }
283:
284: return buffer.toString();
285: }
286:
287: /**
288: * Returns a short string representation of this object.
289: *
290: * @return a short string representation of this object
291: */
292: public String toShortString() {
293: StringBuffer buffer = new StringBuffer();
294: int newline = pattern.indexOf('\n');
295:
296: if (type == STRING_TYPE) {
297: buffer.append("\"");
298: if (newline >= 0) {
299: if (newline > 0 && pattern.charAt(newline - 1) == '\r') {
300: newline--;
301: }
302: buffer.append(pattern.substring(0, newline));
303: buffer.append("(...)");
304: } else {
305: buffer.append(pattern);
306: }
307: buffer.append("\"");
308: } else {
309: buffer.append("<");
310: buffer.append(name);
311: buffer.append(">");
312: }
313:
314: return buffer.toString();
315: }
316: }
|