KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > languages > lexer > SLexer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.languages.lexer;
21
22 import java.util.Iterator JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26 import org.netbeans.api.languages.CharInput;
27 import org.netbeans.api.languages.ASTToken;
28 import org.netbeans.api.lexer.PartType;
29 import org.netbeans.api.languages.LanguagesManager;
30 import org.netbeans.api.languages.ParseException;
31 import org.netbeans.api.lexer.Token;
32 import org.netbeans.api.languages.ASTToken;
33 import org.netbeans.modules.languages.Feature;
34 import org.netbeans.modules.languages.Feature.Type;
35 import org.netbeans.modules.languages.Language;
36 import org.netbeans.modules.languages.LanguagesManagerImpl;
37 import org.netbeans.modules.languages.parser.Pattern;
38 import org.netbeans.spi.lexer.Lexer;
39 import org.netbeans.spi.lexer.LexerInput;
40 import org.netbeans.spi.lexer.LexerRestartInfo;
41 import org.netbeans.spi.lexer.TokenFactory;
42 import org.netbeans.modules.languages.parser.Parser;
43 import org.netbeans.spi.lexer.TokenPropertyProvider;
44
45
46 /**
47  *
48  * @author Jan Jancura
49  */

50 public class SLexer implements Lexer<STokenId>, Parser.Cookie {
51     
52     private Language language;
53     private CharInput input;
54     private TokenFactory<STokenId> tokenFactory;
55     private Map JavaDoc<String JavaDoc,STokenId> tokensMap;
56     private Parser parser;
57     private Object JavaDoc state;
58     
59     
60     SLexer (
61         Language language,
62         Map JavaDoc<String JavaDoc,STokenId> tokensMap,
63         LexerRestartInfo<STokenId> info
64     ) {
65         this.language = language;
66         this.tokenFactory = info.tokenFactory ();
67         this.tokensMap = tokensMap;
68         this.state = info.state ();
69         parser = language.getParser ();
70         String JavaDoc outerMimeType = info.languagePath ().language (0).mimeType ();
71         try {
72             Language outerLanguage = ((LanguagesManagerImpl) LanguagesManager.getDefault ()).
73                 getLanguage (outerMimeType);
74             this.input = createInputBridge (info.input (), outerLanguage);
75         } catch (ParseException ex) {
76             this.input = createInputBridge (info.input (), new Language (outerMimeType));
77         }
78     }
79     
80     public Token<STokenId> nextToken () {
81         Token<STokenId> t = nextTokenIn ();
82 // if (t == null)
83
// System.out.println("nextToken (" + language.getMimeType () + "): null");
84
// else
85
// System.out.println("nextToken (" + language.getMimeType () + "): " + t.id ().name ());
86
return t;
87     }
88     
89     private Token<STokenId> nextTokenIn () {
90         if (state instanceof Marenka) {
91             return createToken ((Marenka) state);
92         }
93         int index = input.getIndex ();
94         if (input.eof ())
95             return createToken (index);
96         ASTToken token = null;
97         token = parser.read (this, input, language.getMimeType ());
98         if (language != null &&
99             tokenProperties != null &&
100             tokenProperties.getType ("call") != Type.NOT_SET
101         ) {
102             input.setIndex (index);
103             Object JavaDoc[] r = (Object JavaDoc[]) tokenProperties.getValue ("call", new Object JavaDoc[] {input});
104             token = (ASTToken) r [0];
105             if (r [1] != null)
106                 setState (((Integer JavaDoc) r [1]).intValue ());
107         }
108         
109         if (token == null) {
110             if (input.getIndex () > (index + 1))
111                 input.setIndex (index + 1);
112             else
113             if (input.getIndex () == index)
114                 input.read ();
115             return createToken ("error", index);
116         }
117         return createToken (token.getType (), index);
118     }
119
120     public Object JavaDoc state () {
121         return state;
122     }
123
124     public void release() {
125     }
126
127     
128     // Cookie implementation ...................................................
129

130     private Feature tokenProperties;
131     
132     public int getState () {
133         if (state == null) return -1;
134         return ((Integer JavaDoc) state).intValue ();
135     }
136
137     public void setState (int state) {
138         this.state = new Integer JavaDoc (state);
139     }
140
141     public void setProperties (Feature tokenProperties) {
142         this.tokenProperties = tokenProperties;
143     }
144     
145     
146     // other methods ...........................................................
147

148     private static CharInput createInputBridge (
149         LexerInput input,
150         Language language
151     ) {
152         Feature properties = language.getPreprocessorImport ();
153         if (properties != null) {
154             return new DelegatingInputBridge (
155                 new InputBridge (input),
156                 properties.getPattern ("start"),
157                 properties.getPattern ("end"),
158                 "PE"//(String) properties.get ("token")
159
);
160         }
161         return new InputBridge (input);
162     }
163     
164     private Token<STokenId> createToken (String JavaDoc type, int start) {
165         STokenId tokenId = tokensMap.get (type);
166         assert tokenId != null : "Unknown token type \"" + type + "\"";
167         if (!(input instanceof DelegatingInputBridge)) {
168             return tokenFactory.createToken (tokenId);
169         }
170         List JavaDoc embeddings = ((DelegatingInputBridge) input).getEmbeddings ();
171         if (embeddings.isEmpty ())
172             return tokenFactory.createToken (tokenId);
173         Map JavaDoc<String JavaDoc,Feature> imports = language.getTokenImports ();
174         if (imports.containsKey (type))
175             // no preprocessor imports in token import.
176
return tokenFactory.createToken (tokenId);
177         Marenka marenka = new Marenka ((Integer JavaDoc) state);
178         String JavaDoc property = "S";
179         Iterator JavaDoc it = embeddings.iterator ();
180         while(it.hasNext ()) {
181             Vojta v = (Vojta) it.next ();
182             if (start < v.startOffset) {
183                 marenka.add (new Vojta (type, start, v.startOffset, property));
184                 property = "C";
185             }
186             marenka.add (v);
187             start = v.endOffset;
188         }
189         if (start < input.getIndex ())
190             marenka.add (new Vojta (type, start, input.getIndex (), property));
191         return createToken (marenka);
192     }
193     
194     private Token<STokenId> createToken (int start) {
195         if (!(input instanceof DelegatingInputBridge)) {
196             return null;
197         }
198         List JavaDoc embeddings = ((DelegatingInputBridge) input).getEmbeddings ();
199         if (embeddings.isEmpty ())
200             return null;
201         Marenka marenka = new Marenka ((Integer JavaDoc) state);
202         String JavaDoc property = "S";
203         Iterator JavaDoc it = embeddings.iterator ();
204         while(it.hasNext ()) {
205             Vojta v = (Vojta) it.next ();
206             assert start == v.startOffset;
207             marenka.add (v);
208             start = v.endOffset;
209         }
210         assert start == input.getIndex ();
211         return createToken (marenka);
212     }
213     
214     private Token<STokenId> createToken (Marenka marenka) {
215         Vojta v = marenka.removeFirst ();
216         STokenId tokenId = tokensMap.get (v.type);
217         assert tokenId != null : "Unknown type " + v.type;
218         input.setIndex (v.endOffset);
219         if (marenka.isEmpty ())
220             this.state = marenka.getState ();
221         else
222             this.state = marenka;
223         //S ystem.out.println("nextToken <" + v.type + "," + e (input.getString (v.startOffset, v.endOffset)) + "," + v.startOffset + "," + v.endOffset);
224
if (v.property instanceof TokenProperties)
225             return tokenFactory.createPropertyToken (
226                 tokenId,
227                 v.endOffset - v.startOffset,
228                 (TokenProperties) v.property,
229                 PartType.COMPLETE
230             );
231         else
232             return tokenFactory.createPropertyToken (
233                 tokenId,
234                 v.endOffset - v.startOffset,
235                 new TokenPropProvider(v.property),
236                 PartType.COMPLETE
237             );
238     }
239         
240     private static String JavaDoc e (CharSequence JavaDoc t) {
241         StringBuilder JavaDoc sb = new StringBuilder JavaDoc ();
242         int i, k = t.length ();
243         for (i = 0; i < k; i++) {
244             if (t.charAt (i) == '\t')
245                 sb.append ("\\t");
246             else
247             if (t.charAt (i) == '\r')
248                 sb.append ("\\r");
249             else
250             if (t.charAt (i) == '\n')
251                 sb.append ("\\n");
252             else
253                 sb.append (t.charAt (i));
254         }
255         return sb.toString ();
256     }
257     
258     
259     // innerclasses ............................................................
260

261     private static final class TokenPropProvider implements TokenPropertyProvider {
262         
263         private final Object JavaDoc value;
264         
265         TokenPropProvider(Object JavaDoc value) {
266             this.value = value;
267         }
268         
269         public Object JavaDoc getValue (Token token, Object JavaDoc key) {
270             if ("type".equals(key))
271                 return value;
272             return null;
273         }
274
275     }
276     
277     static class TokenProperties implements TokenPropertyProvider {
278         
279         private String JavaDoc type;
280         private int startSkipLength;
281         private int endSkipLength;
282         
283         TokenProperties (
284             String JavaDoc type,
285             int startSkipLength,
286             int endSkipLength
287         ) {
288             this.type = type;
289             this.startSkipLength = startSkipLength;
290             this.endSkipLength = endSkipLength;
291         }
292         
293         public Object JavaDoc getValue (Token token, Object JavaDoc key) {
294             if ("type".equals (key)) return type;
295             if ("startSkipLength".equals (key)) return new Integer JavaDoc (startSkipLength);
296             if ("endSkipLength".equals (key)) return new Integer JavaDoc (endSkipLength);
297             return null;
298         }
299
300     };
301     
302     static class Vojta {
303         
304         String JavaDoc type;
305         int startOffset;
306         int endOffset;
307         Object JavaDoc property;
308         
309         Vojta (
310             String JavaDoc type,
311             int startOffset,
312             int endOffset,
313             Object JavaDoc property
314         ) {
315             this.type = type;
316             this.startOffset = startOffset;
317             this.endOffset = endOffset;
318             this.property = property;
319         }
320         
321         int size () {
322             return endOffset - startOffset;
323         }
324     }
325     
326     static class Marenka {
327         
328         Integer JavaDoc state;
329         LinkedList JavaDoc<Vojta> vojta = new LinkedList JavaDoc<Vojta> ();
330         
331         Marenka (Integer JavaDoc state) {
332             this.state = state;
333         }
334         
335         void add (Vojta vojta) {
336             this.vojta.add (vojta);
337         }
338         
339         Vojta removeFirst () {
340             return vojta.removeFirst ();
341         }
342         
343         boolean isEmpty () {
344             return vojta.isEmpty ();
345         }
346         
347         Integer JavaDoc getState () {
348             return state;
349         }
350     }
351 }
352
353
354
Popular Tags