KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > triactive > jdo > store > Parser


1 /*
2  * Copyright 2002 (C) TJDO.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the TJDO License version 1.0.
6  * See the terms of the TJDO License in the documentation provided with this software.
7  *
8  * $Id: Parser.java,v 1.3 2003/02/04 23:23:38 jackknifebarber Exp $
9  */

10
11 package com.triactive.jdo.store;
12
13 import com.triactive.jdo.util.Imports;
14 import java.math.BigDecimal JavaDoc;
15 import java.math.BigInteger JavaDoc;
16 import java.text.CharacterIterator JavaDoc;
17 import java.text.StringCharacterIterator JavaDoc;
18 import javax.jdo.JDOUserException;
19
20
21 class Parser
22 {
23     private final String JavaDoc input;
24     private final Imports imports;
25     private final CharacterIterator JavaDoc ci;
26
27
28     public Parser(String JavaDoc input, Imports imports)
29     {
30         this.input = input;
31         this.imports = imports;
32
33         ci = new StringCharacterIterator JavaDoc(input);
34     }
35
36
37     public String JavaDoc getInput()
38     {
39         return input;
40     }
41
42
43     public int getIndex()
44     {
45         return ci.getIndex();
46     }
47
48
49     public int skipWS()
50     {
51         int startIdx = ci.getIndex();
52         char c = ci.current();
53
54         while (Character.isWhitespace(c))
55             c = ci.next();
56
57         return startIdx;
58     }
59
60
61     public boolean parseEOS()
62     {
63         skipWS();
64
65         return ci.current() == CharacterIterator.DONE;
66     }
67
68
69     public boolean parseChar(char c)
70     {
71         skipWS();
72
73         if (ci.current() == c)
74         {
75             ci.next();
76             return true;
77         }
78         else
79             return false;
80     }
81
82
83     public boolean parseChar(char c, char unlessFollowedBy)
84     {
85         int savedIdx = skipWS();
86
87         if (ci.current() == c && ci.next() != unlessFollowedBy)
88             return true;
89         else
90         {
91             ci.setIndex(savedIdx);
92             return false;
93         }
94     }
95
96
97     public boolean parseString(String JavaDoc s)
98     {
99         int savedIdx = skipWS();
100
101         int len = s.length();
102         char c = ci.current();
103
104         for (int i = 0; i < len; ++i)
105         {
106             if (c != s.charAt(i))
107             {
108                 ci.setIndex(savedIdx);
109                 return false;
110             }
111
112             c = ci.next();
113         }
114
115         return true;
116     }
117
118
119     public boolean parseString(String JavaDoc s, char unlessFollowedBy)
120     {
121         int savedIdx = skipWS();
122
123         if (parseString(s) && ci.next() != unlessFollowedBy)
124             return true;
125         else
126         {
127             ci.setIndex(savedIdx);
128             return false;
129         }
130     }
131
132
133     public String JavaDoc parseIdentifier()
134     {
135         skipWS();
136         char c = ci.current();
137
138         if (!Character.isJavaIdentifierStart(c))
139             return null;
140
141         StringBuffer JavaDoc id = new StringBuffer JavaDoc().append(c);
142
143         while (Character.isJavaIdentifierPart(c = ci.next()))
144             id.append(c);
145
146         return id.toString();
147     }
148
149
150     public String JavaDoc parseName()
151     {
152         int savedIdx = skipWS();
153         String JavaDoc id;
154
155         if ((id = parseIdentifier()) == null)
156             return null;
157
158         StringBuffer JavaDoc qn = new StringBuffer JavaDoc(id);
159
160         while (parseChar('.'))
161         {
162             if ((id = parseIdentifier()) == null)
163             {
164                 ci.setIndex(savedIdx);
165                 return null;
166             }
167
168             qn.append('.').append(id);
169         }
170
171         return qn.toString();
172     }
173
174
175     public Class JavaDoc parseCast()
176     {
177         int savedIdx = skipWS();
178         String JavaDoc typeName;
179
180         if (!parseChar('(') || (typeName = parseName()) == null || !parseChar(')'))
181         {
182             ci.setIndex(savedIdx);
183             return null;
184         }
185
186         try
187         {
188             return imports.resolveClassDeclaration(typeName);
189         }
190         catch (ClassNotFoundException JavaDoc e)
191         {
192             ci.setIndex(savedIdx);
193             return null;
194         }
195     }
196
197
198     private final static boolean isDecDigit(char c)
199     {
200         return c >= '0' && c <= '9';
201     }
202
203
204     private final static boolean isOctDigit(char c)
205     {
206         return c >= '0' && c <= '7';
207     }
208
209
210     private final static boolean isHexDigit(char c)
211     {
212         return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';
213     }
214
215
216     public BigInteger JavaDoc parseIntegerLiteral()
217     {
218         int savedIdx = skipWS();
219
220         StringBuffer JavaDoc digits = new StringBuffer JavaDoc();
221         int radix;
222         char c = ci.current();
223
224         if (c == '0')
225         {
226             c = ci.next();
227
228             if (c == 'x' || c == 'X')
229             {
230                 radix = 16;
231                 c = ci.next();
232
233                 while (isHexDigit(c))
234                 {
235                     digits.append(c);
236                     c = ci.next();
237                 }
238             }
239             else if (isOctDigit(c))
240             {
241                 radix = 8;
242
243                 do
244                 {
245                     digits.append(c);
246                     c = ci.next();
247                 } while (isOctDigit(c));
248             }
249             else
250             {
251                 radix = 10;
252                 digits.append('0');
253             }
254         }
255         else
256         {
257             radix = 10;
258
259             while (isDecDigit(c))
260             {
261                 digits.append(c);
262                 c = ci.next();
263             }
264         }
265
266         if (digits.length() == 0)
267         {
268             ci.setIndex(savedIdx);
269             return null;
270         }
271
272         if (c == 'l' || c == 'L')
273             ci.next();
274
275         return new BigInteger JavaDoc(digits.toString(), radix);
276     }
277
278
279     public BigDecimal JavaDoc parseFloatingPointLiteral()
280     {
281         int savedIdx = skipWS();
282         StringBuffer JavaDoc val = new StringBuffer JavaDoc();
283         boolean dotSeen = false;
284         boolean expSeen = false;
285         boolean sfxSeen = false;
286
287         char c = ci.current();
288
289         while (isDecDigit(c))
290         {
291             val.append(c);
292             c = ci.next();
293         }
294
295         if (c == '.')
296         {
297             dotSeen = true;
298             val.append(c);
299             c = ci.next();
300
301             while (isDecDigit(c))
302             {
303                 val.append(c);
304                 c = ci.next();
305             }
306         }
307
308         if (val.length() < (dotSeen ? 2 : 1))
309         {
310             ci.setIndex(savedIdx);
311             return null;
312         }
313
314         if (c == 'e' || c == 'E')
315         {
316             expSeen = true;
317             val.append(c);
318             c = ci.next();
319
320             if (c != '+' && c != '-' && !isDecDigit(c))
321             {
322                 ci.setIndex(savedIdx);
323                 return null;
324             }
325
326             do
327             {
328                 val.append(c);
329                 c = ci.next();
330             } while (isDecDigit(c));
331         }
332
333         if (c == 'f' || c == 'F' || c == 'd' || c == 'D')
334         {
335             sfxSeen = true;
336             ci.next();
337         }
338
339         if (!dotSeen && !expSeen && !sfxSeen)
340         {
341             ci.setIndex(savedIdx);
342             return null;
343         }
344
345         return new BigDecimal JavaDoc(val.toString());
346     }
347
348
349     public Boolean JavaDoc parseBooleanLiteral()
350     {
351         int savedIdx = skipWS();
352         String JavaDoc id;
353
354         if ((id = parseIdentifier()) == null)
355             return null;
356
357         if (id.equals("true"))
358             return Boolean.TRUE;
359         else if (id.equals("false"))
360             return Boolean.FALSE;
361         else
362         {
363             ci.setIndex(savedIdx);
364             return null;
365         }
366     }
367
368
369     public Character JavaDoc parseCharacterLiteral()
370     {
371         skipWS();
372
373         if (ci.current() != '\'')
374             return null;
375
376         char c = ci.next();
377
378         if (c == CharacterIterator.DONE)
379             throw new JDOUserException("Invalid character literal: " + input);
380
381         if (c == '\\')
382             c = parseEscapedCharacter();
383
384         if (ci.next() != '\'')
385             throw new JDOUserException("Invalid character literal: " + input);
386
387         ci.next();
388
389         return new Character JavaDoc(c);
390     }
391
392
393     public String JavaDoc parseStringLiteral()
394     {
395         skipWS();
396
397         if (ci.current() != '"')
398             return null;
399
400         StringBuffer JavaDoc lit = new StringBuffer JavaDoc();
401         char c;
402
403         while ((c = ci.next()) != '"')
404         {
405             if (c == CharacterIterator.DONE)
406                 throw new JDOUserException("Invalid string literal: " + input);
407
408             if (c == '\\')
409                 c = parseEscapedCharacter();
410
411             lit.append(c);
412         }
413
414         ci.next();
415
416         return lit.toString();
417     }
418
419
420     private char parseEscapedCharacter()
421     {
422         char c;
423
424         if (isOctDigit(c = ci.next()))
425         {
426             int i = (int)(c - '0');
427
428             if (isOctDigit(c = ci.next()))
429             {
430                 i = i * 8 + (int)(c - '0');
431
432                 if (isOctDigit(c = ci.next()))
433                     i = i * 8 + (int)(c - '0');
434                 else
435                     ci.previous();
436             }
437             else
438                 ci.previous();
439
440             if (i > 0xff)
441                 throw new JDOUserException("Invalid character escape: '\\" + Integer.toOctalString(i) + "'");
442
443             return (char)i;
444         }
445         else
446         {
447             switch (c)
448             {
449                 case 'b': return '\b';
450                 case 't': return '\t';
451                 case 'n': return '\n';
452                 case 'f': return '\f';
453                 case 'r': return '\r';
454                 case '"': return '"';
455                 case '\'': return '\'';
456                 case '\\': return '\\';
457                 default:
458                     throw new JDOUserException("Invalid character escape: '\\" + c + "'");
459             }
460         }
461     }
462
463
464     public boolean parseNullLiteral()
465     {
466         int savedIdx = skipWS();
467         String JavaDoc id;
468
469         if ((id = parseIdentifier()) == null)
470             return false;
471         else if (id.equals("null"))
472             return true;
473         else
474         {
475             ci.setIndex(savedIdx);
476             return false;
477         }
478     }
479 }
480
Popular Tags