1 19 20 package org.netbeans.modules.lexer.editorbridge.calc.lang; 21 22 import java.util.HashMap ; 23 import java.util.Map ; 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 37 38 public final class CalcLexer implements Lexer<CalcTokenId> { 39 40 private static final int EOF = LexerInput.EOF; 41 42 private static final Map <String ,CalcTokenId> keywords = new HashMap <String ,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); } 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 '/': 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 '*': 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 } 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)) { while (true) { 124 if (ch == EOF || !Character.isLetter((char)ch)) { 125 input.backup(1); CalcTokenId id = keywords.get(input.readText()); 128 if (id == null) { 129 id = CalcTokenId.IDENTIFIER; 130 } 131 return token(id); 132 } 133 ch = input.read(); } 135 } 136 137 return token(CalcTokenId.ERROR); 138 } 139 } 140 } 141 142 public Object 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': 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 |