KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > lexer > editorbridge > calc > lang > CalcLexer


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.lexer.editorbridge.calc.lang;
21
22 import java.util.HashMap JavaDoc;
23 import java.util.Map JavaDoc;
24 import org.netbeans.api.lexer.Token;
25 import org.netbeans.spi.lexer.Lexer;
26 import org.netbeans.spi.lexer.LexerInput;
27 import org.netbeans.spi.lexer.LexerRestartInfo;
28 import org.netbeans.spi.lexer.TokenFactory;
29
30
31 /**
32  * Lexer for the Calc Language.
33  *
34  * @author Miloslav Metelka
35  * @version 1.00
36  */

37
38 public final class CalcLexer implements Lexer<CalcTokenId> {
39
40     private static final int EOF = LexerInput.EOF;
41
42     private static final Map JavaDoc<String JavaDoc,CalcTokenId> keywords = new HashMap JavaDoc<String JavaDoc,CalcTokenId>();
43     static {
44         keywords.put(CalcTokenId.E.fixedText(), CalcTokenId.E);
45         keywords.put(CalcTokenId.PI.fixedText(), CalcTokenId.PI);
46     }
47     
48     private LexerInput input;
49     
50     private TokenFactory<CalcTokenId> tokenFactory;
51
52     CalcLexer(LexerRestartInfo<CalcTokenId> info) {
53         this.input = info.input();
54         this.tokenFactory = info.tokenFactory();
55         assert (info.state() == null); // passed argument always null
56
}
57     
58     public Token<CalcTokenId> nextToken() {
59         while (true) {
60             int ch = input.read();
61             switch (ch) {
62                 case '+':
63                     return token(CalcTokenId.PLUS);
64
65                 case '-':
66                     return token(CalcTokenId.MINUS);
67
68                 case '*':
69                     return token(CalcTokenId.STAR);
70
71                 case '/':
72                     switch (input.read()) {
73                         case '/': // in single-line comment
74
while (true)
75                                 switch (input.read()) {
76                                     case '\r': input.consumeNewline();
77                                     case '\n':
78                                     case EOF:
79                                         return token(CalcTokenId.LINE_COMMENT);
80                                 }
81                         case '*': // in multi-line comment
82
while (true) {
83                                 ch = input.read();
84                                 while (ch == '*') {
85                                     ch = input.read();
86                                     if (ch == '/')
87                                         return token(CalcTokenId.BLOCK_COMMENT);
88                                     else if (ch == EOF)
89                                         return token(CalcTokenId.BLOCK_COMMENT_INCOMPLETE);
90                                 }
91                                 if (ch == EOF)
92                                     return token(CalcTokenId.BLOCK_COMMENT_INCOMPLETE);
93                             }
94                     } // end of switch()
95
input.backup(1);
96                     return token(CalcTokenId.SLASH);
97
98                 case '(':
99                     return token(CalcTokenId.LPAREN);
100
101                 case ')':
102                     return token(CalcTokenId.RPAREN);
103
104                 case '0': case '1': case '2': case '3': case '4':
105                 case '5': case '6': case '7': case '8': case '9':
106                 case '.':
107                     return finishIntOrFloatLiteral(ch);
108
109                 case EOF:
110                     return null;
111
112                 default:
113                     if (Character.isWhitespace((char)ch)) {
114                         ch = input.read();
115                         while (ch != EOF && Character.isWhitespace((char)ch)) {
116                             ch = input.read();
117                         }
118                         input.backup(1);
119                         return token(CalcTokenId.WHITESPACE);
120                     }
121
122                     if (Character.isLetter((char)ch)) { // identifier or keyword
123
while (true) {
124                             if (ch == EOF || !Character.isLetter((char)ch)) {
125                                 input.backup(1); // backup the extra char (or EOF)
126
// Check for keywords
127
CalcTokenId id = keywords.get(input.readText());
128                                 if (id == null) {
129                                     id = CalcTokenId.IDENTIFIER;
130                                 }
131                                 return token(id);
132                             }
133                             ch = input.read(); // read next char
134
}
135                     }
136
137                     return token(CalcTokenId.ERROR);
138             }
139         }
140     }
141
142     public Object JavaDoc state() {
143         return null;
144     }
145
146     private Token<CalcTokenId> finishIntOrFloatLiteral(int ch) {
147         boolean floatLiteral = false;
148         boolean inExponent = false;
149         while (true) {
150             switch (ch) {
151                 case '.':
152                     if (floatLiteral) {
153                         return token(CalcTokenId.FLOAT_LITERAL);
154                     } else {
155                         floatLiteral = true;
156                     }
157                     break;
158                 case '0': case '1': case '2': case '3': case '4':
159                 case '5': case '6': case '7': case '8': case '9':
160                     break;
161                 case 'e': case 'E': // exponent part
162
if (inExponent) {
163                         return token(CalcTokenId.FLOAT_LITERAL);
164                     } else {
165                         floatLiteral = true;
166                         inExponent = true;
167                     }
168                     break;
169                 default:
170                     input.backup(1);
171                     return token(floatLiteral ? CalcTokenId.FLOAT_LITERAL
172                             : CalcTokenId.INT_LITERAL);
173             }
174             ch = input.read();
175         }
176     }
177     
178     private Token<CalcTokenId> token(CalcTokenId id) {
179         return (id.fixedText() != null)
180             ? tokenFactory.getFlyweightToken(id, id.fixedText())
181             : tokenFactory.createToken(id);
182     }
183
184     public void release() {
185     }
186
187 }
Popular Tags