4b0b14828936010469a1384a04a081b101f9203f
[mir.git] / source / mir / util / SimpleParser.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License, 
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
23  * (or with modified versions of the above that use the same license as the above), 
24  * and distribute linked combinations including the two.  You must obey the 
25  * GNU General Public License in all respects for all of the code used other than 
26  * the above mentioned libraries.  If you modify this file, you may extend this 
27  * exception to your version of the file, but you are not obligated to do so.  
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30
31 package mir.util;
32
33 import gnu.regexp.RE;
34 import gnu.regexp.REException;
35 import gnu.regexp.REMatch;
36 import multex.Exc;
37 import multex.Failure;
38
39 /**
40  * Simple parser. Can be used to parse a <code>String</code> based using
41  * regular epxression.
42  */
43 public class SimpleParser {
44   private String data;
45   private int position;
46
47   /**
48    * Initialize a new <code>SimpleParser</code>, with <code>aData</code>
49    * as the text to parse.
50    */
51
52   public SimpleParser(String aData) {
53     data=aData;
54     position=0;
55   }
56
57   /**
58    * Parses a regular expression. Uses suppled <code>aMessage</code> parameter
59    * in case of an error.
60    */
61   public String parse(RE aRegularExpression, String aMessage) throws SimpleParserExc {
62     REMatch match = aRegularExpression.getMatch(data, position);
63
64     if (match==null || match.getStartIndex()!=position) {
65       throw new SimpleParserExc(aMessage+" at position "+position+" in '"+data+"'");
66     }
67
68     position=match.getEndIndex();
69
70     return match.toString();
71   }
72
73   /**
74    * Attempts to match the data right after the parsing position to
75    * a regular expression
76    *
77    * @throws SimpleParserExc if no match could be found for the given regular
78    * expression.
79    */
80   public String parse(RE aRegularExpression) throws SimpleParserExc {
81     return parse( aRegularExpression, "No match found for '"+aRegularExpression.toString()+"'");
82   }
83
84   /**
85    * Attempts to skip data at the parsing position matching the supplied regular expression
86    *
87    * @throws SimpleParserExc if no match could be found for the given regular
88    * expression.
89    */
90
91   public void skip(RE aRegularExpression) throws SimpleParserExc {
92     REMatch match = aRegularExpression.getMatch(data, position);
93
94     if (match!=null && match.getStartIndex()==position)
95       position=match.getEndIndex();
96   }
97
98   /**
99    * Returns <code>true</code> if the data at the parsing position matches the given
100    * regular expression.
101    */
102   public boolean parses(String anExpression) throws SimpleParserExc {
103     try {
104       return parses(new RE(anExpression));
105     }
106     catch (SimpleParserExc e) {
107       throw e;
108     }
109     catch (REException e) {
110       throw new SimpleParserFailure( "Error compiling regular expression '" + anExpression + "': " + e.getMessage(), e);
111     }
112     catch (Throwable t) {
113       throw new SimpleParserFailure( t );
114     }
115   }
116
117   /**
118    * Returns <code>true</code> if the data at the parsing position matches the given
119    * regular expression.
120    */
121   public boolean parses(RE aRegularExpression) throws SimpleParserExc {
122     REMatch match = aRegularExpression.getMatch(data, position);
123
124     return (match!=null && match.getStartIndex()==position) ;
125   }
126
127   /**
128    * Attempts to match the data right after the parsing position to
129    * a regular expression
130    *
131    * @throws SimpleParserExc if no match could be found for the given regular
132    * expression.
133    */
134   public String parse(String anExpression) throws SimpleParserExc, SimpleParserFailure {
135     try {
136       return parse(new RE(anExpression));
137     }
138     catch (SimpleParserExc e) {
139       throw e;
140     }
141     catch (REException e) {
142       throw new SimpleParserFailure( "Error compiling regular expression '" + anExpression + "': " + e.getMessage(), e);
143     }
144     catch (Throwable t) {
145       throw new SimpleParserFailure( t );
146     }
147   }
148
149
150   /**
151    * Parses text at the current parsing position matching the given <code>anExpression</code>.
152    * Will apply the supplied message to an exception if no match could be found.
153    */
154   public String parse(String anExpression, String aMessage) throws SimpleParserExc, SimpleParserFailure {
155     try {
156       return parse(new RE(anExpression), aMessage);
157     }
158     catch (SimpleParserExc e) {
159       throw e;
160     }
161     catch (REException e) {
162       throw new SimpleParserFailure( "Error compiling regular expression '" + anExpression + "': " + e.getMessage(), e);
163     }
164     catch (Throwable t) {
165       throw new SimpleParserFailure( t );
166     }
167   }
168
169   /**
170    * Skips (i.e. discards) text matching the supplied regular expression
171    */
172
173   public void skip(String anExpression) throws SimpleParserExc, SimpleParserFailure {
174     try {
175       skip(new RE(anExpression));
176     }
177     catch (SimpleParserExc e) {
178       throw e;
179     }
180     catch (REException e) {
181       throw new SimpleParserFailure( "Error compiling regular expression '" + anExpression + "': " + e.getMessage(), e);
182     }
183     catch (Throwable t) {
184       throw new SimpleParserFailure( t );
185     }
186   }
187
188   /**
189    * returns <code>true</code> if the parser is at the end of the data
190    */
191   public boolean isAtEnd() {
192     return position>=data.length();
193   }
194
195   /**
196    * Returns the "remaining" data: the data after the current position
197    */
198   public String remainingData() {
199     return data.substring(position);
200   }
201
202   /**
203    * Unchecked exception thrown from <code>SimpleParser</code>
204    */
205
206   public static class SimpleParserFailure extends Failure {
207     public SimpleParserFailure(Throwable aThrowable) {
208       super(aThrowable.getMessage(), aThrowable);
209     }
210
211     public SimpleParserFailure(String aMessage, Throwable aThrowable) {
212       super(aMessage, aThrowable);
213     }
214   }
215
216   /**
217    * Checked exception thrown from <code>SimpleParser</code>
218    */
219   public static class SimpleParserExc extends Exc {
220     public SimpleParserExc(String aMessage) {
221       super(aMessage);
222     }
223   }
224 }