1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package fr.ove.openmath.jome.ctrl.linear;
30
31 import java.util.*;
32
33 import org.util.activemath.JomeConstants;
34
35 import fr.ove.openmath.jome.ctrl.linear.events.*;
36 import fr.ove.utils.*;
37
38 /***
39 * A bean which parses, more precisely tokenizes, what we can call the linear form of an expression.<BR>
40 * For each specific token encountered, an event (@see LinearParserEvent) is fired to all the listeners
41 * (@see LinearParserListener) of the instance.<BR>
42 * The event fired is made of 2 parts :
43 * <UL>
44 * <LI> the token identifier (for example, for + (addition) the associated identifier is
45 * <CODE>LinearParserEvent.ADDITION</CODE>)</LI>
46 * <LI> the value of the token, if needed. (for example, when the digit 2 is encountered, the identifier
47 * has the <CODE>LinearParserEvent.INTEGER</CODE> value, and the token value is represented by the @see String "2")</LI>
48 * </UL>
49 * When the parsing starts, an event whith the identifier set to <CODE>LinearParserEvent.START_EXPRESSION</CODE> is
50 * fired.
51 * Similarly, when the parsing ends (the end of the linear form has been reached), an event whith the identifier
52 * set to <CODE>LinearParserEvent.END_EXPRESSION</CODE> is fired.<BR>
53 * In order to make distinctions between what should be variables and special keywords, a resources file
54 * (LinearParserResources.properties) is attached to the parser. This file contains the user defined keywords.<BR>
55 * To add your own keywords, edit this properties file with respect to the used format (see this file for further
56 * details).
57 *
58 * @author Ôø? 1999 DIRAT Laurent
59 * @version 1.0 27/09/1999
60 */
61 public class LinearParser implements java.io.Serializable {
62 /***
63 * The parser resources manager.<BR>
64 * Reads into the properties file (LinearParserResources.properties) to get the user defined specific
65 * keywords.
66 */
67 private ResourcesManager resourcesManager;
68
69 /***
70 * The list of listeners of the instance
71 */
72 private Vector listeners = new Vector();
73
74 /***
75 * The event sent to all the listeners of the instance during the parsing.
76 */
77 private LinearParserEvent linearParserEvent = new LinearParserEvent(this);
78
79 /***
80 * The constructor.
81 */
82 public LinearParser() {
83 resourcesManager = new ResourcesManager("fr.ove.openmath.jome.ctrl.linear.LinearParserResources");
84 }
85
86 /***
87 * Registers another listener of the instance.
88 * @param linearParserListener the listener to add.
89 */
90 public synchronized void addLinearParserListener(LinearParserListener linearParserListener) {
91 listeners.addElement(linearParserListener);
92 }
93
94 /***
95 * Removes a listener.
96 * @param linearParserListener the listener to remove.
97 */
98 public synchronized void removeLinearParserListener(LinearParserListener linearParserListener) {
99 listeners.removeElement(linearParserListener);
100 }
101
102 /***
103 * Fires a LinearParserEvent event to registered listeners.
104 * @param linearParserEvent event encapsulating relevant information.
105 */
106 public void fireLinearParserEvent(LinearParserEvent linearParserEvent) {
107 for (int i = 0; i < listeners.size(); i++)
108 ((LinearParserListener) listeners.elementAt(i)).consumeLinearParserEvent(linearParserEvent);
109 }
110
111 /***
112 * Parses the specified linear form of the formula.
113 * @param expression the linear form of the formula.
114 */
115 public void parse(String expression) {
116
117 int nbTokenUsed = 0;
118
119
120 StringTokenizer theTokens = new StringTokenizer(expression, "+-/*^_()=<>;, {}[]//?!", true);
121
122 StringTokenizer tmpTokens = null;
123
124 String token = null;
125
126 String nextToken = null;
127
128
129 linearParserEvent.setToken(LinearParserEvent.START_EXPRESSION, null);
130 fireLinearParserEvent(linearParserEvent);
131
132 boolean isSpecial = false;
133
134 int tokenCount = theTokens.countTokens();
135 while (theTokens.hasMoreTokens()) {
136 token = theTokens.nextToken();
137 nbTokenUsed++;
138
139 if (token.equals(" "))
140 continue;
141 else if (token.equals("+"))
142 if ( isSpecial)
143 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token);
144 else
145 linearParserEvent.setToken(LinearParserEvent.ADDITION, token);
146 else if (token.equals("-"))
147 if ( isSpecial)
148 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token);
149 else
150 linearParserEvent.setToken(LinearParserEvent.SUBSTRACTION, token);
151 else if (token.equals("*"))
152 if ( isSpecial)
153 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token);
154 else
155 linearParserEvent.setToken(LinearParserEvent.MULTIPLICATION, token);
156 else if (token.equals("/"))
157 if ( isSpecial)
158 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token);
159 else
160 linearParserEvent.setToken(LinearParserEvent.DIVISION, token);
161 else if (token.equals("^"))
162 linearParserEvent.setToken(LinearParserEvent.POWER, token);
163 else if (token.equals("(")){
164
165 linearParserEvent.setToken(LinearParserEvent.FUNCTION2, token);
166 fireLinearParserEvent(linearParserEvent);
167 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token);
168 fireLinearParserEvent(linearParserEvent);
169 linearParserEvent.setToken(LinearParserEvent.SEPARATOR, "");
170
171
172 }else if (token.equals(")"))
173 linearParserEvent.setToken(LinearParserEvent.CLOSE_PAREN, token);
174
175 else if (token.equals("{"))
176
177 linearParserEvent.setToken(LinearParserEvent.FUNCTION2, token);
178 else if (token.equals("}"))
179
180 linearParserEvent.setToken(LinearParserEvent.CLOSE_CURLY, null);
181 else if (token.equals("[")){
182 linearParserEvent.setToken(LinearParserEvent.FUNCTION2, token);
183 fireLinearParserEvent(linearParserEvent);
184 linearParserEvent.setToken(LinearParserEvent.OPEN_BRACKET, token);
185 }else if (token.equals("]"))
186 linearParserEvent.setToken(LinearParserEvent.CLOSE_BRACKET, token);
187 else if (token.equals("_"))
188 linearParserEvent.setToken(LinearParserEvent.UNDERSCRIPT, token);
189 else if (token.equals(",") || token.equals(";"))
190 linearParserEvent.setToken(LinearParserEvent.SEPARATOR, token);
191 else if (token.equals("//")){
192
193 tmpTokens = new StringTokenizer(expression, "+-/*^_()=<>;, {}[]//?!", true );
194 for (int i = 0; i < nbTokenUsed + 1; i++) {
195 try {
196 nextToken = tmpTokens.nextToken();
197 }
198 catch (NoSuchElementException e) {
199 nextToken = null;
200 }
201 }
202
203 if (nextToken != null ) {
204 String token2 = token+nextToken;
205 String str2 = null;
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 if (JomeConstants.SYMBOLS.containsKey(token2)){
223 theTokens.nextToken();
224 nbTokenUsed++;
225 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token2);
226 }
227
228
229
230
231
232 else{
233
234
235
236 isSpecial = true;
237 continue;
238 }
239
240 }
241
242
243 }else if (token.equals("<") || token.equals(">")) {
244
245
246 tmpTokens = new StringTokenizer(expression, "+-/*^_()=<>;, {}[]//?!", true );
247 for (int i = 0; i < nbTokenUsed + 1; i++) {
248 try {
249 nextToken = tmpTokens.nextToken();
250 }
251 catch (NoSuchElementException e) {
252 nextToken = null;
253 }
254 }
255
256 if (token.equals("<")) {
257 if (nextToken != null ) {
258 if (nextToken.equals("=")) {
259 theTokens.nextToken();
260 nbTokenUsed++;
261 linearParserEvent.setToken(LinearParserEvent.LESSEQUAL, "<=");
262 }
263 else if (nextToken.equals(">")) {
264 theTokens.nextToken();
265 nbTokenUsed++;
266 linearParserEvent.setToken(LinearParserEvent.UNEQUAL, "<>");
267 }
268 else
269 linearParserEvent.setToken(LinearParserEvent.LESS, token);
270 }
271 else
272 linearParserEvent.setToken(LinearParserEvent.LESS, token);
273 }
274 else if(token.equals(">")) {
275 if (nextToken != null ) {
276 if (nextToken.equals("=")) {
277 theTokens.nextToken();
278 nbTokenUsed++;
279 linearParserEvent.setToken(LinearParserEvent.GREATEREQUAL, ">=");
280 }
281 else
282 linearParserEvent.setToken(LinearParserEvent.GREATER, token);
283 }
284 else
285 linearParserEvent.setToken(LinearParserEvent.GREATER, token);
286 } else
287 linearParserEvent.setToken(LinearParserEvent.SPECIALIZED, token);
288 }
289 else if (token.equals("="))
290 if ( isSpecial)
291 linearParserEvent.setToken(LinearParserEvent.SYMBOL, token);
292 else
293 linearParserEvent.setToken(LinearParserEvent.EQUAL, token);
294
295
296
297 else if (token.equals("?"))
298 linearParserEvent.setToken(LinearParserEvent.SPECIALIZED, token);
299 else if (token.equals("!"))
300 linearParserEvent.setToken(LinearParserEvent.SPECIALIZED, "fact");
301 else {
302 if (NumberUtils.isNumber(token)) {
303 if (NumberUtils.isFloat(token))
304 linearParserEvent.setToken(LinearParserEvent.FLOAT, token);
305 else
306 linearParserEvent.setToken(LinearParserEvent.INTEGER, token);
307 }
308 else {
309
310
311
312
313
314
315 tmpTokens = new StringTokenizer(expression, "+-/*^_()=<>;, {}[]//?!", true );
316 for (int i = 0; i < nbTokenUsed + 1; i++) {
317 try {
318 nextToken = tmpTokens.nextToken();
319 }
320 catch (NoSuchElementException e) {
321 nextToken = null;
322 }
323 }
324
325 if (nextToken != null) {
326 if (nextToken.equals("(") && !isSpecial) {
327
328 linearParserEvent.setToken(LinearParserEvent.FUNCTION , token);
329
330
331
332
333
334
335 theTokens.nextToken();
336 nbTokenUsed++;
337
338
339 }
340 else {
341 String str1 = resourcesManager.getResourceString(token);
342 if (isSpecial || str1 == null)
343
344 linearParserEvent.setToken(LinearParserEvent.VARIABLE, token);
345 else
346 linearParserEvent.setToken(
347 (str1.equals("RESERVED") ? LinearParserEvent.RESERVED : LinearParserEvent.SPECIALIZED),
348 token);
349 }
350 }
351 else {
352 String str2 = resourcesManager.getResourceString(token);
353 if (isSpecial || str2 == null)
354
355 linearParserEvent.setToken(LinearParserEvent.VARIABLE, token);
356 else
357 linearParserEvent.setToken(
358 (str2.equals("RESERVED") ? LinearParserEvent.RESERVED : LinearParserEvent.SPECIALIZED),
359 token);
360 }
361 }
362 }
363
364 fireLinearParserEvent(linearParserEvent);
365 isSpecial = false;
366 }
367
368
369 linearParserEvent.setToken(LinearParserEvent.END_EXPRESSION, null);
370 fireLinearParserEvent(linearParserEvent);
371 }
372
373
374 public static void main(String args[]) {
375 LinearParserListener l = new LinearParserListener() {
376 public void consumeLinearParserEvent(LinearParserEvent linearParserEvent) {
377 System.out.println(linearParserEvent.toString());
378 }
379 };
380
381 LinearParser lp = new LinearParser();
382 lp.addLinearParserListener(l);
383 lp.parse("1+2+23+C+in+pi+x_8");
384 }
385 }