KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > parsec > Terms


1 /*****************************************************************************
2  * Copyright (C) Zephyr Business Solutions Corp. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  *****************************************************************************/

8 /*
9  * Created on Nov 20, 2004
10  *
11  * Author Ben Yu
12  */

13 package jfun.parsec;
14
15
16 import jfun.parsec.tokens.MyToken;
17 import jfun.parsec.tokens.TokenQuoted;
18 import jfun.parsec.tokens.TokenType;
19 //import jfun.parsec.scanner.Lexers;
20

21
22
23 /**
24  * This helper class provides convenient api's to build lexer
25  * and parsers for terminals.
26  * @author Ben Yu
27  *
28  * Nov 20, 2004
29  */

30 public final class Terms implements java.io.Serializable JavaDoc{
31   private final Words words;
32   /**
33    * gets the parser for the terminals identified by tnames.
34    * The Tok object is returned from the result parser.
35    * @param tnames the names of the terminals.
36    * @return the Parser.
37    */

38   public Parser<Tok> getParser(final String JavaDoc... tnames){
39     return getParser(tnames, toLabel(tnames));
40   }
41   /**
42    * gets the parser for the terminals identified by tnames.
43    * The Tok object is returned.
44    * @param name the name of the parser.
45    * @param tnames the names of the terminals.
46    * @return the Parser.
47    */

48   public Parser<Tok> getParser(final String JavaDoc name, final String JavaDoc[] tnames){
49     return getParser(name, tnames, toLabel(tnames));
50   }
51   /**
52    * gets the parser for the terminals identified by tnames.
53    * The Tok object is returned from the result parser.
54    * @param tnames the names of the terminals.
55    * @param expected the label when this parser fails.
56    * @return the Parser.
57    */

58   public Parser<Tok> getParser(final String JavaDoc[] tnames, final String JavaDoc expected){
59     return getParser("term", tnames, expected);
60   }
61   /**
62    * gets the parser for the terminals identified by tnames.
63    * The Tok object is returned from the result parser.
64    * @param name the name of the parser.
65    * @param tnames the names of the terminals.
66    * @param expected the label when this parser fails.
67    * @return the Parser.
68    */

69   public Parser<Tok> getParser(final String JavaDoc name, final String JavaDoc[] tnames,
70       final String JavaDoc expected){
71     if(tnames.length == 0) return Parsers.zero(name);
72     final Parser<Tok>[] ps = new Parser[tnames.length];
73     for(int i=0; i<tnames.length; i++){
74       ps[i] = Parsers.token(isToken(words.getToken(tnames[i])));
75     }
76     return Parsers.plus(name, ps).label(name, expected);
77   }
78   /**
79    * gets the parser for a terminal identified by tname.
80    * The Tok object is returned from the result parser.
81    * @param name the name of the parser.
82    * @param tname the name of the terminal.
83    * @param expected the label when this parser fails.
84    * @return the Parser.
85    */

86   public Parser<Tok> getParser(final String JavaDoc name, final String JavaDoc tname,
87       final String JavaDoc expected){
88     return Parsers.token(name, isToken(words.getToken(tname)))
89       .label(name, expected);
90   }
91   /**
92    * gets the parser for a terminal identified by tname.
93    * The Tok object is returned from the result parser.
94    * @param tname the name of the terminal.
95    * @param expected the label when this parser fails.
96    * @return the Parser.
97    */

98   public Parser<Tok> getParser(final String JavaDoc tname, final String JavaDoc expected){
99     return getParser("term", tname, expected);
100   }
101   /**
102    * gets the parser for a terminal identified by tname.
103    * The Tok object is returned from the result parser.
104    * @param tname the name of the terminal.
105    * @return the Parser.
106    */

107   public Parser<Tok> getParser(final String JavaDoc tname){
108     return getParser(tname, tname);
109   }
110   /**
111    * gets the lexer for the terminals.
112    * @return the lexer.
113    */

114   public Parser<Tok> getLexer(){
115     return words.getLexer();
116   }
117   /**
118    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
119    * and for lexing and parsing the keywords case insensitively.
120    * Keywords and operators are lexed as TokenReserved.
121    * Words that are not among the keywords are lexed as TokenWord.
122    * A word is defined as an alpha numeric string that starts with [_a-zA-Z],
123    * with 0 or more [0-9_a-zA-Z] following.
124    * @param ops the operator names.
125    * @param keywords the keyword names.
126    * @return the Terms instance.
127    * @since version 1.1
128    */

129   public static Terms getCaseInsensitiveInstance(final String JavaDoc[] ops, final String JavaDoc[] keywords){
130     return new Terms(Lexers.getCaseInsensitive(ops, keywords));
131   }
132   /**
133    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
134    * and for lexing and parsing the keywords case sensitively.
135    * Keywords and operators are lexed as TokenReserved.
136    * Words that are not among the keywords are lexed as TokenWord.
137    * A word is defined as an alpha numeric string that starts with [_a-zA-Z],
138    * with 0 or more [0-9_a-zA-Z] following.
139    * @param ops the operator names.
140    * @param keywords the keyword names.
141    * @return the Terms instance.
142    * @since version 1.1
143    */

144   public static Terms getCaseSensitiveInstance(final String JavaDoc[] ops, final String JavaDoc[] keywords){
145     return new Terms(Lexers.getCaseSensitive(ops, keywords));
146   }
147   /**
148    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
149    * and for lexing and parsing the keywords case insensitively.
150    * Keywords and operators are lexed as TokenReserved.
151    * Words that are not among the keywords are lexed as TokenWord.
152    * @param wscanner the scanner that identifies a word in the language.
153    * @param ops the operator names.
154    * @param keywords the keyword names.
155    * @return the Terms instance.
156    * @since version 1.1
157    */

158   public static Terms getCaseInsensitiveInstance(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords){
159     return new Terms(Lexers.getCaseInsensitive(wscanner, ops, keywords));
160   }
161   /**
162    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
163    * and for lexing and parsing the keywords case sensitively.
164    * Keywords and operators are lexed as TokenReserved.
165    * Words that are not among the keywords are lexed as TokenWord.
166    * @param wscanner the scanner that identifies a word in the language.
167    * @param ops the operator names.
168    * @param keywords the keyword names.
169    * @return the Terms instance.
170    * @since version 1.1
171    */

172   public static Terms getCaseSensitiveInstance(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords){
173     return new Terms(Lexers.getCaseSensitive(wscanner, ops, keywords));
174   }
175   
176   /**
177    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
178    * and for lexing and parsing the keywords case insensitively.
179    * Keywords and operators are lexed as TokenReserved.
180    * Words that are not among the keywords are lexed as TokenWord.
181    * @param wscanner the scanner that identifies a word in the language.
182    * @param ops the operator names.
183    * @param keywords the keyword names.
184    * @param toWord the FromString object used to create a token for non-key words recognized by wscanner.
185    * @return the Terms instance.
186    * @since version 1.1
187    */

188   public static Terms getCaseInsensitiveInstance(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords,
189       FromString<?> toWord){
190     return new Terms(Lexers.getCaseInsensitive(wscanner, ops, keywords, toWord));
191   }
192   /**
193    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
194    * and for lexing and parsing the keywords case sensitively.
195    * Keywords and operators are lexed as TokenReserved.
196    * Words that are not among the keywords are lexed as TokenWord.
197    * @param wscanner the scanner that identifies a word in the language.
198    * @param ops the operator names.
199    * @param keywords the keyword names.
200    * @param toWord the FromString object used to create a token for non-key words recognized by wscanner.
201    * @return the Terms instance.
202    * @since version 1.1
203    */

204   public static Terms getCaseSensitiveInstance(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords,
205       FromString<?> toWord){
206     return new Terms(Lexers.getCaseSensitive(wscanner, ops, keywords, toWord));
207   }
208   /**
209    * Creates a Terms object for lexing the operators with names specified in ops.
210    * Operators are lexed as TokenReserved.
211    * @param ops the operator names.
212    * @return the Terms instance.
213    * @since version 1.1
214    */

215   public static Terms getOperatorsInstance(final String JavaDoc... ops){
216     return new Terms(Lexers.getOperators(ops));
217   }
218   
219   /**
220    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
221    * and for lexing and parsing the keywords case insensitively.
222    * Keywords and operators are lexed as TokenReserved.
223    * Words that are not among the keywords are lexed as TokenWord.
224    * A word is defined as an alpha numeric string that starts with [_a-zA-Z],
225    * with 0 or more [0-9_a-zA-Z] following.
226    * @param ops the operator names.
227    * @param keywords the keyword names.
228    * @return the Terms instance.
229    * @deprecated Use {@link #getCaseInsensitiveInstance(String[], String[])} instead.
230    */

231   public static Terms getCaseInsensitive(final String JavaDoc[] ops, final String JavaDoc[] keywords){
232     return getCaseInsensitiveInstance(ops, keywords);
233   }
234   /**
235    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
236    * and for lexing and parsing the keywords case sensitively.
237    * Keywords and operators are lexed as TokenReserved.
238    * Words that are not among the keywords are lexed as TokenWord.
239    * A word is defined as an alpha numeric string that starts with [_a-zA-Z],
240    * with 0 or more [0-9_a-zA-Z] following.
241    * @param ops the operator names.
242    * @param keywords the keyword names.
243    * @return the Terms instance.
244    * @deprecated Use {@link #getCaseSensitiveInstance(String[], String[])} instead.
245    */

246   public static Terms getCaseSensitive(final String JavaDoc[] ops, final String JavaDoc[] keywords){
247     return getCaseSensitiveInstance(ops, keywords);
248   }
249   /**
250    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
251    * and for lexing and parsing the keywords case insensitively.
252    * Keywords and operators are lexed as TokenReserved.
253    * Words that are not among the keywords are lexed as TokenWord.
254    * @param wscanner the scanner that identifies a word in the language.
255    * @param ops the operator names.
256    * @param keywords the keyword names.
257    * @return the Terms instance.
258    * @deprecated Use {@link #getCaseInsensitiveInstance(Parser, String[], String[])} instead.
259    */

260   public static Terms getCaseInsensitive(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords){
261     return getCaseInsensitiveInstance(wscanner, ops, keywords);
262   }
263   /**
264    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
265    * and for lexing and parsing the keywords case sensitively.
266    * Keywords and operators are lexed as TokenReserved.
267    * Words that are not among the keywords are lexed as TokenWord.
268    * @param wscanner the scanner that identifies a word in the language.
269    * @param ops the operator names.
270    * @param keywords the keyword names.
271    * @return the Terms instance.
272    * @deprecated Use {@link #getCaseSensitiveInstance(Parser, String[], String[])} instead.
273    */

274   public static Terms getCaseSensitive(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords){
275     return getCaseSensitiveInstance(wscanner, ops, keywords);
276   }
277   
278   /**
279    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
280    * and for lexing and parsing the keywords case insensitively.
281    * Keywords and operators are lexed as TokenReserved.
282    * Words that are not among the keywords are lexed as TokenWord.
283    * @param wscanner the scanner that identifies a word in the language.
284    * @param ops the operator names.
285    * @param keywords the keyword names.
286    * @param toWord the FromString object used to create a token for non-key words recognized by wscanner.
287    * @return the Terms instance.
288    * @deprecated Use {@link #getCaseInsensitiveInstance(Parser, String[], String[], FromString)} instead.
289    */

290   public static Terms getCaseInsensitive(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords,
291       FromString<?> toWord){
292     return getCaseInsensitiveInstance(wscanner, ops, keywords, toWord);
293   }
294   /**
295    * Creates a Terms object for lexing and parsing the operators with names specified in ops,
296    * and for lexing and parsing the keywords case sensitively.
297    * Keywords and operators are lexed as TokenReserved.
298    * Words that are not among the keywords are lexed as TokenWord.
299    * @param wscanner the scanner that identifies a word in the language.
300    * @param ops the operator names.
301    * @param keywords the keyword names.
302    * @param toWord the FromString object used to create a token for non-key words recognized by wscanner.
303    * @return the Terms instance.
304    * @deprecated Use {@link #getCaseSensitiveInstance(Parser, String[], String[], FromString)} instead.
305    */

306   public static Terms getCaseSensitive(final Parser<?> wscanner, final String JavaDoc[] ops, final String JavaDoc[] keywords,
307       FromString<?> toWord){
308     return getCaseSensitiveInstance(wscanner, ops, keywords, toWord);
309   }
310   /**
311    * Creates a Terms object for lexing the operators with names specified in ops.
312    * Operators are lexed as TokenReserved.
313    * @param ops the operator names.
314    * @return the Terms instance.
315    * @deprecated Use {@link #getOperatorsInstance(String[])} instead.
316    */

317   public static Terms getOperators(final String JavaDoc... ops){
318     return getOperatorsInstance(ops);
319   }
320   
321   
322   /**
323    * gets a Parser object to parse Character token.
324    * @param name the parser name.
325    * @param fc the mapping to map char to an object returned by the parser.
326    * @return the parser
327    */

328   public static <R> Parser<R> charParser(final String JavaDoc name, final FromChar<R> fc){
329     return Parsers.token(name, new FromToken<R>(){
330       public R fromToken(Tok ptok){
331         final Object JavaDoc t = ptok.getToken();
332         if(t instanceof Character JavaDoc){
333           final Character JavaDoc c = (Character JavaDoc)t;
334           return fc.fromChar(ptok.getIndex(), ptok.getLength(), c.charValue());
335         }
336         else return null;
337       }
338     });
339   }
340   /**
341    * gets a Parser object to parse String token.
342    * @param name the parser name.
343    * @param fc the mapping to map String to an object returned by the parser.
344    * @return the parser
345    */

346   public static <R> Parser<R> stringParser(final String JavaDoc name, final FromString<R> fc){
347     return Parsers.token(name, new FromToken<R>(){
348       public R fromToken(Tok ptok){
349         final Object JavaDoc t = ptok.getToken();
350         if(t instanceof String JavaDoc){
351           return fc.fromString(ptok.getIndex(), ptok.getLength(), t.toString());
352         }
353         else return null;
354       }
355     });
356   }
357   /**
358    * gets a Parser object to parse TokenQuoted.
359    * @param name the parser name.
360    * @param fc the mapping to map the quoted string to an object returned by the parser.
361    * @return the parser
362    */

363   public static <R> Parser<R> quotedWordParser(final String JavaDoc name, final FromString3<R> fc){
364     return Parsers.token(name, new FromToken<R>(){
365       public R fromToken(Tok ptok){
366         final Object JavaDoc t = ptok.getToken();
367         if(t instanceof TokenQuoted){
368           final TokenQuoted c = (TokenQuoted)t;
369           return fc.fromString3(ptok.getIndex(), ptok.getLength(),
370               c.getOpen(), c.getQuoted(), c.getClose());
371         }
372         else return null;
373       }
374     });
375   }
376   /**
377    * gets a Parser object to parse TokenWord.
378    * @param name the parser name.
379    * @param fc the mapping to map the word to an object returned by the parser.
380    * @return the parser
381    */

382   public static <R> Parser<R> wordParser(final String JavaDoc name, final FromString<R> fc){
383     return Parsers.token(name, fromTypedToken(TokenType.Word, fc));
384   }
385   /**
386    * Create a parser that recognizes MyToken object.
387    * @param fm the FromMyText object to recognize MyToken object.
388    * @return the Tokenizer object.
389    */

390   @Deprecated JavaDoc
391   public static <R> Parser<R> myParser(final FromMyText<R> fm){
392     return myParser("myParser", fm);
393   }
394   /**
395    * Create a parser that recognizes MyToken object.
396    * @param name the name of the parser object.
397    * @param fm the FromMyText object to recognize MyToken object.
398    * @return the Tokenizer object.
399    */

400   @Deprecated JavaDoc
401   public static <R> Parser<R> myParser(final String JavaDoc name, final FromMyText<R> fm){
402     return Parsers.token(name, new FromToken<R>(){
403       public R fromToken(Tok ptok){
404         final Object JavaDoc t = ptok.getToken();
405         if(t instanceof MyToken){
406           final MyToken mt = (MyToken)t;
407           return fm.fromMyText(ptok.getIndex(), ptok.getLength(),
408               mt.getText(), mt.getKind());
409         }
410         return null;
411       }
412     });
413   }
414   /**
415    * Create a parser that recognizes MyToken of a certain kind.
416    * @param kind the token kind to recognize.
417    * @param fs the FromString object to transform.
418    * @return the Parser object.
419    */

420   @Deprecated JavaDoc
421   public static <R> Parser<R> myParser(final int kind, final FromString<R> fs){
422     return myParser("myParser", kind, fs);
423   }
424   /**
425    * Create a parser that recognizes MyToken of a certain kind.
426    * @param name the Parser name.
427    * @param kind the token kind to recognize.
428    * @param fs the FromString object to transform.
429    * @return the Parser object.
430    */

431   @Deprecated JavaDoc
432   public static <R> Parser<R> myParser(final String JavaDoc name, final int kind,
433       final FromString<R> fs){
434     return Parsers.token(name, new FromToken<R>(){
435       public R fromToken(Tok ptok){
436         final Object JavaDoc t = ptok.getToken();
437         if(t instanceof MyToken){
438           final MyToken mt = (MyToken)t;
439           if(mt.getKind() != kind) return null;
440           return fs.fromString(ptok.getIndex(), ptok.getLength(), mt.getText());
441         }
442         return null;
443       }
444     });
445     
446   }
447   /**
448    * gets a Parser object to parse Long token.
449    * @param name the parser name.
450    * @param fc the mapping to map the number to an object returned by the parser.
451    * @return the parser
452    */

453   public static <R> Parser<R> integerParser(final String JavaDoc name, final FromLong<R> fc){
454     return Parsers.token(name, new FromToken<R>(){
455       public R fromToken(final Tok ptok){
456         final Object JavaDoc t = ptok.getToken();
457         if(t instanceof Long JavaDoc){
458           final Long JavaDoc c = (Long JavaDoc)t;
459           return fc.fromLong(ptok.getIndex(), ptok.getLength(), c.longValue());
460         }
461         else return null;
462       }
463     });
464   }
465   /**
466    * gets a Parser object to parse token of arbitrary length integer.
467    * @param fs the mapping to map the number to an object returned by the parser.
468    * @return the parser
469    */

470   public static <R> Parser<R> integerParser(final FromString<R> fs){
471     return integerParser("integerParser", fs);
472   }
473   /**
474    * gets a Parser object to parse token of arbitrary length integer.
475    * @param name the parser name.
476    * @param fs the mapping to map the number to an object returned by the parser.
477    * @return the parser
478    */

479   public static <R> Parser<R> integerParser(final String JavaDoc name, final FromString<R> fs){
480     return Parsers.token(name, fromTypedToken(TokenType.Integer, fs));
481   }
482   /**
483    * gets a Parser object to parse TokenDecimal.
484    * @param name the parser name.
485    * @param fc the mapping to map the decimal to an object returned by the parser.
486    * @return the parser
487    */

488   public static <R> Parser<R> decimalParser(final String JavaDoc name, final FromString<R> fc){
489     return Parsers.token(name, fromTypedToken(
490         new TokenType[]{TokenType.Decimal, TokenType.Integer}, fc));
491   }
492   /**
493    * gets a Parser object to parse Character token.
494    * @param fc the mapping to map char to an object returned by the parser.
495    * @return the parser
496    */

497   public static <R> Parser<R> charParser(final FromChar<R> fc){
498     return charParser("char", fc);
499   }
500   /**
501    * gets a Parser object to parse String token.
502    * @param fc the mapping to map String to an object returned by the parser.
503    * @return the parser
504    */

505   public static <R> Parser<R> stringParser(final FromString<R> fc){
506     return stringParser("stringLiteral", fc);
507   }
508   /**
509    * gets a Parser object to parse TokenQuoted.
510    * @param fc the mapping to map the quoted string to an object returned by the parser.
511    * @return the parser
512    */

513   public static <R> Parser<R> quotedWordParser(final FromString3<R> fc){
514     return quotedWordParser("quotedName", fc);
515   }
516   /**
517    * gets a Parser object to parse TokenWord.
518    * @param fc the mapping to map the word to an object returned by the parser.
519    * @return the parser
520    */

521   public static <R> Parser<R> wordParser(final FromString<R> fc){
522     return wordParser("name", fc);
523   }
524   /**
525    * gets a Parser object to parse Long token.
526    * @param fc the mapping to map the number to an object returned by the parser.
527    * @return the parser
528    */

529   public static <R> Parser<R> integerParser(final FromLong<R> fc){
530     return integerParser("integer", fc);
531   }
532   /**
533    * gets a Parser object to parse TokenDecimal.
534    * @param fc the mapping to map the decimal to an object returned by the parser.
535    * @return the parser
536    */

537   public static <R> Parser<R> decimalParser(final FromString<R> fc){
538     return decimalParser("decimal", fc);
539   }
540   /**
541    * Get a FromToken object that only recognizes a token of
542    * a certain type.
543    * @param type the token type recognized.
544    * @param f the FromString object used to translate the character range to
545    * a certain object.
546    * @return the FromToken object.
547    * @since version 1.1
548    */

549   public static <T,R> FromToken<R> fromTypedToken(final T type,
550       final FromString<R> f){
551     return new IsTokenOfType<R>(f){
552       public boolean isOfType(Object JavaDoc t){
553         return t == type;
554       }
555     };
556   }
557   
558   /**
559    * Get a FromToken object that only recognizes a token of
560    * certain types.
561    * @param types the token types recognized.
562    * @param f the FromString object used to translate the character range to
563    * a certain object.
564    * @return the FromToken object.
565    * @since version 1.1
566    */

567   public static <T,R> FromToken<R> fromTypedToken(final T[] types,
568       final FromString<R> f){
569     return new IsTokenOfType<R>(f){
570       public boolean isOfType(Object JavaDoc type){
571         for(T t: types){
572           if(type==t)
573             return true;
574         }
575         return false;
576       }
577     };
578   }
579   private Terms(final Words words){
580     this.words = words;
581   }
582   private static FromToken<Tok> isToken(final Object JavaDoc t){
583     return new FromToken<Tok>(){
584       public Tok fromToken(Tok ptok){
585         final Object JavaDoc obj = ptok.getToken();
586         if(obj != t) return null;
587         return ptok;
588       }
589     };
590   }
591   private static String JavaDoc toLabel(final String JavaDoc[] keys){
592     if(keys.length == 0) return "";
593     final StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
594     buf.append('[').append(keys[0]);
595     for(int i=1; i<keys.length; i++){
596       buf.append(',').append(keys[i]);
597     }
598     buf.append(']');
599     return buf.toString();
600   }
601 }
602
Popular Tags