KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > percederberg > grammatica > parser > re > Matcher


1 /*
2  * Matcher.java
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1
7  * of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307, USA.
18  *
19  * Copyright (c) 2003-2005 Per Cederberg. All rights reserved.
20  */

21
22 package net.percederberg.grammatica.parser.re;
23
24 import java.io.IOException JavaDoc;
25 import java.io.Reader JavaDoc;
26 import java.io.StringReader JavaDoc;
27
28 import net.percederberg.grammatica.parser.LookAheadReader;
29
30 /**
31  * A regular expression string matcher. This class handles the
32  * matching of a specific string with a specific regular expression.
33  * It contains state information about the matching process, as for
34  * example the position of the latest match, and a number of flags
35  * that were set. This class is not thread-safe.
36  *
37  * @author Per Cederberg, <per at percederberg dot net>
38  * @version 1.5
39  */

40 public class Matcher {
41
42     /**
43      * The base regular expression element.
44      */

45     private Element element;
46
47     /**
48      * The input character stream to work with.
49      */

50     private LookAheadReader input;
51
52     /**
53      * The character case ignore flag.
54      */

55     private boolean ignoreCase;
56
57     /**
58      * The start of the latest match found.
59      */

60     private int start;
61
62     /**
63      * The length of the latest match found.
64      */

65     private int length;
66
67     /**
68      * The end of string reached flag. This flag is set if the end
69      * of the string was encountered during the latest match.
70      */

71     private boolean endOfString;
72
73     /**
74      * Creates a new matcher with the specified element.
75      *
76      * @param e the base regular expression element
77      * @param input the input character stream to work with
78      * @param ignoreCase the character case ignore flag
79      */

80     Matcher(Element e, LookAheadReader input, boolean ignoreCase) {
81         this.element = e;
82         this.input = input;
83         this.ignoreCase = ignoreCase;
84         this.start = 0;
85         reset();
86     }
87
88     /**
89      * Checks if this matcher compares in case-insensitive mode.
90      *
91      * @return true if the matching is case-insensitive, or
92      * false otherwise
93      *
94      * @since 1.5
95      */

96     public boolean isCaseInsensitive() {
97         return ignoreCase;
98     }
99
100     /**
101      * Resets the information about the last match. This will clear
102      * all flags and set the match length to a negative value. This
103      * method is automatically called before starting a new match.
104      */

105     public void reset() {
106         length = -1;
107         endOfString = false;
108     }
109
110     /**
111      * Resets the matcher for use with a new input string. This will
112      * clear all flags and set the match length to a negative value.
113      *
114      * @param str the new string to work with
115      *
116      * @since 1.5
117      */

118     public void reset(String JavaDoc str) {
119         reset(new StringReader JavaDoc(str));
120     }
121
122     /**
123      * Resets the matcher for use with a new input string. This will
124      * clear all flags and set the match length to a negative value.
125      *
126      * @param str the new string to work with
127      *
128      * @since 1.5
129      */

130     public void reset(StringBuffer JavaDoc str) {
131         reset(new StringReader JavaDoc(str.toString()));
132     }
133
134     /**
135      * Resets the matcher for use with a new character input stream.
136      * This will clear all flags and set the match length to a
137      * negative value.
138      *
139      * @param input the character input stream
140      *
141      * @since 1.5
142      */

143     public void reset(Reader JavaDoc input) {
144         if (input instanceof LookAheadReader) {
145             reset((LookAheadReader) input);
146         } else {
147             reset(new LookAheadReader(input));
148         }
149     }
150
151     /**
152      * Resets the matcher for use with a new look-ahead character
153      * input stream. This will clear all flags and set the match
154      * length to a negative value.
155      *
156      * @param input the character input stream
157      *
158      * @since 1.5
159      */

160     private void reset(LookAheadReader input) {
161         this.input = input;
162         reset();
163     }
164
165     /**
166      * Returns the start position of the latest match. If no match has
167      * been encountered, this method returns zero (0).
168      *
169      * @return the start position of the latest match
170      */

171     public int start() {
172         return start;
173     }
174
175     /**
176      * Returns the end position of the latest match. This is one
177      * character after the match end, i.e. the first character after
178      * the match. If no match has been encountered, this method
179      * returns the same value as start().
180      *
181      * @return the end position of the latest match
182      */

183     public int end() {
184         if (length > 0) {
185             return start + length;
186         } else {
187             return start;
188         }
189     }
190
191     /**
192      * Returns the length of the latest match.
193      *
194      * @return the length of the latest match, or
195      * -1 if no match was found
196      */

197     public int length() {
198         return length;
199     }
200
201     /**
202      * Checks if the end of the string was encountered during the last
203      * match attempt. This flag signals that more input may be needed
204      * in order to get a match (or a longer match).
205      *
206      * @return true if the end of string was encountered, or
207      * false otherwise
208      */

209     public boolean hasReadEndOfString() {
210         return endOfString;
211     }
212
213     /**
214      * Sets the end of string encountered flag. This method is called
215      * by the various elements analyzing the string.
216      */

217     void setReadEndOfString() {
218         endOfString = true;
219     }
220
221     /**
222      * Attempts to find a match starting at the beginning of the
223      * string.
224      *
225      * @return true if a match was found, or
226      * false otherwise
227      *
228      * @throws IOException if an I/O error occurred while reading an
229      * input stream
230      */

231     public boolean matchFromBeginning() throws IOException JavaDoc {
232         return matchFrom(0);
233     }
234
235     /**
236      * Attempts to find a match starting at the specified position in
237      * the string.
238      *
239      * @param pos the starting position of the match
240      *
241      * @return true if a match was found, or
242      * false otherwise
243      *
244      * @throws IOException if an I/O error occurred while reading an
245      * input stream
246      */

247     public boolean matchFrom(int pos) throws IOException JavaDoc {
248         reset();
249         start = pos;
250         length = element.match(this, input, start, 0);
251         return length >= 0;
252     }
253
254     /**
255      * Returns the latest matched string. If no string has been
256      * matched, an empty string will be returned.
257      *
258      * @return the latest matched string
259      */

260     public String JavaDoc toString() {
261         if (length <= 0) {
262             return "";
263         } else {
264             try {
265                 return input.peekString(start, length);
266             } catch (IOException JavaDoc ignore) {
267                 return "";
268             }
269         }
270     }
271 }
272
Popular Tags