KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > parsec > Words


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 Dec 19, 2004
10  *
11  * Author Ben Yu
12  */

13 package jfun.parsec;
14
15 import jfun.parsec.pattern.Patterns;
16
17
18
19 /**
20  * This helper class provides convenient api's to build lexer
21  * and parsers for keywords and operators.
22  * @author Ben Yu
23  *
24  * Dec 19, 2004
25  */

26 public final class Words implements java.io.Serializable JavaDoc{
27   private final Map<String JavaDoc, Object JavaDoc> words;
28   private final Parser<Tok> lexer;
29   private Words(final Map<String JavaDoc, Object JavaDoc> map, final Parser<Tok> lexer){
30     this.words = map;
31     this.lexer = lexer;
32   }
33
34   /**
35    * gets the token object identified by the token text.
36    * This text is the operator or the keyword.
37    * @param name the token text.
38    * @return the token object.
39    * @exception IllegalArgumentException if the token object does not exist.
40    */

41   public Object JavaDoc getToken(final String JavaDoc name){
42     final Object JavaDoc p = words.map(name);
43     if(p==null) throw new IllegalArgumentException JavaDoc("token " + name + " unavailable");
44     return p;
45   }
46   /**
47    * gets the lexer object.
48    * @return the lexer object.
49    */

50   public Parser<Tok> getLexer(){
51     return lexer;
52   }
53   private static boolean same(final String JavaDoc a, final String JavaDoc b, final boolean cs){
54     if(cs){
55       return a.equals(b);
56     }
57     else
58       return a.equalsIgnoreCase(b);
59   }
60   private static void checkDup(final String JavaDoc[] a, final String JavaDoc[] b, boolean cs){
61     for(int i=0; i<a.length; i++){
62       final String JavaDoc s1 = a[i];
63       for(int j=0; j<b.length; j++){
64         final String JavaDoc s2 = b[j];
65         if(same(s1, s2, cs)) throw new IllegalArgumentException JavaDoc(s1 + " duplicated");
66       }
67     }
68   }
69   /**
70    * Creates a Words object for lexing the operators with names specified in ops.
71    * Operators are lexed as TypedToken with TokenType.Reserved type.
72    * @param ops the operator names.
73    * @return the Words instance.
74    */

75   static Words getOperators(final String JavaDoc[] ops){
76     final WordsData data = Operators.instance(ops);
77     //return toWords(data);
78
return new Words(data.getTokens(), Parsers.plus(data.getLexers()));
79   }
80   private static final Parser<?> default_word = Scanners.isPattern(Patterns.isWord(), "word");
81   /**
82    * Creates a Words object for lexing the operators with names specified in ops,
83    * and for lexing the keywords case insensitively.
84    * Keywords and operators are lexed as TypedToken with TokenType.Reserved type.
85    * Words that are not among the keywords are lexed as TokenWord.
86    * A word is defined as an alpha numeric string that starts with [_a-zA-Z],
87    * with 0 or more [0-9_a-zA-Z] following.
88    * @param ops the operator names.
89    * @param keywords the keyword names.
90    * @return the Words instance.
91    */

92   static Words getCaseInsensitive(
93       final String JavaDoc[] ops, final String JavaDoc[] keywords){
94     return instance(default_word, ops, keywords, false, String2TokenWord.instance());
95   }
96   /**
97    * Creates a Words object for lexing the operators with names specified in ops,
98    * and for lexing the keywords case sensitively.
99    * Keywords and operators are lexed as TypedToken with TokenType.Reserved type.
100    * Words that are not among the keywords are lexed as TokenWord.
101    * A word is defined as an alpha numeric string that starts with [_a-zA-Z],
102    * with 0 or more [0-9_a-zA-Z] following.
103    * @param ops the operator names.
104    * @param keywords the keyword names.
105    * @return the Words instance.
106    */

107   static Words getCaseSensitive(
108       final String JavaDoc[] ops, final String JavaDoc[] keywords){
109     return instance(default_word, ops, keywords, true, String2TokenWord.instance());
110   }
111   /**
112    * Creates a Words object for lexing the operators with names specified in ops,
113    * and for lexing the keywords case insensitively.
114    * Keywords and operators are lexed as TypedToken with TokenType.Reserved type.
115    * Words that are not among the keywords are lexed as TokenWord.
116    * @param wscanner the scanner for a word in the language.
117    * @param ops the operator names.
118    * @param keywords the keyword names.
119    * @return the Words instance.
120    */

121   static Words getCaseInsensitive(final Parser<?> wscanner,
122       final String JavaDoc[] ops, final String JavaDoc[] keywords){
123     return instance(wscanner, ops, keywords, false, String2TokenWord.instance());
124   }
125   /**
126    * Creates a Words object for lexing the operators with names specified in ops,
127    * and for lexing the keywords case sensitively.
128    * Keywords and operators are lexed as TypedToken with TokenType.Reserved type.
129    * Words that are not among the keywords are lexed as TokenWord.
130    * @param wscanner the scanner for a word in the language.
131    * @param ops the operator names.
132    * @param keywords the keyword names.
133    * @return the Words instance.
134    */

135   static Words getCaseSensitive(final Parser<?> wscanner,
136       final String JavaDoc[] ops, final String JavaDoc[] keywords){
137     return instance(wscanner, ops, keywords, true, String2TokenWord.instance());
138   }
139   
140   static Words getCaseSensitive(final Parser<?> wscanner, String JavaDoc[] ops, final String JavaDoc[] keywords,
141       FromString<?> toWord){
142     return instance(wscanner, ops, keywords, true, toWord);
143   }
144   static Words getCaseInsensitive(final Parser<?> wscanner, String JavaDoc[] ops, String JavaDoc[] keywords,
145       FromString<?> toWord){
146     return instance(wscanner, ops, keywords, false, toWord);
147   }
148   private static Words instance(final Parser<?> wscanner,
149       final String JavaDoc[] ops, final String JavaDoc[] keywords, final boolean cs,
150       FromString<?> toWord){
151     checkDup(ops, keywords, true);
152     final WordsData data = combine(Operators.instance(ops),
153         Keywords.getInstance("word", wscanner, keywords, cs, toWord));
154     return toWords(data);
155   }
156   private static Words toWords(WordsData data){
157     return new Words(data.getTokens(), Parsers.plus(data.getLexers()));
158   }
159   private static WordsData combine(final WordsData w1, final WordsData w2){
160     final Map<String JavaDoc, Object JavaDoc> map1 = w1.getTokens();
161     final Map<String JavaDoc, Object JavaDoc> map2 = w2.getTokens();
162     final Parser<Tok>[] l1 = w1.getLexers();
163     final Parser<Tok>[] l2 = w2.getLexers();
164     final Map<String JavaDoc, Object JavaDoc> map = new Map<String JavaDoc, Object JavaDoc>(){
165       public Object JavaDoc map(final String JavaDoc k){
166         final Object JavaDoc r = map1.map(k);
167         if(r!=null) return r;
168         return map2.map(k);
169       }
170     };
171     final Parser<Tok>[] l = new Parser[l1.length+l2.length];
172     /*for(int i=0; i<l1.length; i++){
173       l[i] = l1[i];
174     }
175     for(int i=0; i<l2.length; i++){
176       l[i+l1.length] = l2[i];
177     }*/

178     System.arraycopy(l1, 0, l, 0, l1.length);
179     System.arraycopy(l2, 0, l, l1.length, l2.length);
180     return new WordsData(map, l);
181   }
182 }
183
Popular Tags