src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java

Mon, 24 Oct 2011 13:00:20 +0100

author
mcimadamore
date
Mon, 24 Oct 2011 13:00:20 +0100
changeset 1113
d346ab55031b
child 1125
56830d5cb5bb
permissions
-rw-r--r--

7096014: Javac tokens should retain state
Summary: Refactor javac tokens from enum constants to stateful instances (to keep track of position, comments, etc.)
Reviewed-by: jjg

mcimadamore@1113 1 /*
mcimadamore@1113 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1113 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1113 4 *
mcimadamore@1113 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1113 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1113 7 * published by the Free Software Foundation. Oracle designates this
mcimadamore@1113 8 * particular file as subject to the "Classpath" exception as provided
mcimadamore@1113 9 * by Oracle in the LICENSE file that accompanied this code.
mcimadamore@1113 10 *
mcimadamore@1113 11 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1113 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1113 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1113 14 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1113 15 * accompanied this code).
mcimadamore@1113 16 *
mcimadamore@1113 17 * You should have received a copy of the GNU General Public License version
mcimadamore@1113 18 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1113 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1113 20 *
mcimadamore@1113 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1113 22 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1113 23 * questions.
mcimadamore@1113 24 */
mcimadamore@1113 25
mcimadamore@1113 26 package com.sun.tools.javac.parser;
mcimadamore@1113 27
mcimadamore@1113 28 import java.nio.CharBuffer;
mcimadamore@1113 29 import com.sun.tools.javac.code.Source;
mcimadamore@1113 30 import com.sun.tools.javac.util.*;
mcimadamore@1113 31
mcimadamore@1113 32
mcimadamore@1113 33 import static com.sun.tools.javac.parser.Tokens.*;
mcimadamore@1113 34 import static com.sun.tools.javac.util.LayoutCharacters.*;
mcimadamore@1113 35
mcimadamore@1113 36 /** The lexical analyzer maps an input stream consisting of
mcimadamore@1113 37 * ASCII characters and Unicode escapes into a token sequence.
mcimadamore@1113 38 *
mcimadamore@1113 39 * <p><b>This is NOT part of any supported API.
mcimadamore@1113 40 * If you write code that depends on this, you do so at your own risk.
mcimadamore@1113 41 * This code and its internal interfaces are subject to change or
mcimadamore@1113 42 * deletion without notice.</b>
mcimadamore@1113 43 */
mcimadamore@1113 44 public class JavaTokenizer {
mcimadamore@1113 45
mcimadamore@1113 46 private static boolean scannerDebug = false;
mcimadamore@1113 47
mcimadamore@1113 48 /** Allow hex floating-point literals.
mcimadamore@1113 49 */
mcimadamore@1113 50 private boolean allowHexFloats;
mcimadamore@1113 51
mcimadamore@1113 52 /** Allow binary literals.
mcimadamore@1113 53 */
mcimadamore@1113 54 private boolean allowBinaryLiterals;
mcimadamore@1113 55
mcimadamore@1113 56 /** Allow underscores in literals.
mcimadamore@1113 57 */
mcimadamore@1113 58 private boolean allowUnderscoresInLiterals;
mcimadamore@1113 59
mcimadamore@1113 60 /** The source language setting.
mcimadamore@1113 61 */
mcimadamore@1113 62 private Source source;
mcimadamore@1113 63
mcimadamore@1113 64 /** The log to be used for error reporting.
mcimadamore@1113 65 */
mcimadamore@1113 66 private final Log log;
mcimadamore@1113 67
mcimadamore@1113 68 /** The name table. */
mcimadamore@1113 69 private final Names names;
mcimadamore@1113 70
mcimadamore@1113 71 /** The token factory. */
mcimadamore@1113 72 private final Tokens tokens;
mcimadamore@1113 73
mcimadamore@1113 74 /** The token kind, set by nextToken().
mcimadamore@1113 75 */
mcimadamore@1113 76 protected TokenKind tk;
mcimadamore@1113 77
mcimadamore@1113 78 /** The token's radix, set by nextToken().
mcimadamore@1113 79 */
mcimadamore@1113 80 protected int radix;
mcimadamore@1113 81
mcimadamore@1113 82 /** The token's name, set by nextToken().
mcimadamore@1113 83 */
mcimadamore@1113 84 protected Name name;
mcimadamore@1113 85
mcimadamore@1113 86 /** The position where a lexical error occurred;
mcimadamore@1113 87 */
mcimadamore@1113 88 protected int errPos = Position.NOPOS;
mcimadamore@1113 89
mcimadamore@1113 90 /** Has a @deprecated been encountered in last doc comment?
mcimadamore@1113 91 * this needs to be reset by client.
mcimadamore@1113 92 */
mcimadamore@1113 93 protected boolean deprecatedFlag = false;
mcimadamore@1113 94
mcimadamore@1113 95 /** A character buffer for saved chars.
mcimadamore@1113 96 */
mcimadamore@1113 97 protected char[] sbuf = new char[128];
mcimadamore@1113 98 protected int sp;
mcimadamore@1113 99
mcimadamore@1113 100 protected UnicodeReader reader;
mcimadamore@1113 101
mcimadamore@1113 102 private static final boolean hexFloatsWork = hexFloatsWork();
mcimadamore@1113 103 private static boolean hexFloatsWork() {
mcimadamore@1113 104 try {
mcimadamore@1113 105 Float.valueOf("0x1.0p1");
mcimadamore@1113 106 return true;
mcimadamore@1113 107 } catch (NumberFormatException ex) {
mcimadamore@1113 108 return false;
mcimadamore@1113 109 }
mcimadamore@1113 110 }
mcimadamore@1113 111
mcimadamore@1113 112 /**
mcimadamore@1113 113 * Create a scanner from the input array. This method might
mcimadamore@1113 114 * modify the array. To avoid copying the input array, ensure
mcimadamore@1113 115 * that {@code inputLength < input.length} or
mcimadamore@1113 116 * {@code input[input.length -1]} is a white space character.
mcimadamore@1113 117 *
mcimadamore@1113 118 * @param fac the factory which created this Scanner
mcimadamore@1113 119 * @param input the input, might be modified
mcimadamore@1113 120 * @param inputLength the size of the input.
mcimadamore@1113 121 * Must be positive and less than or equal to input.length.
mcimadamore@1113 122 */
mcimadamore@1113 123 protected JavaTokenizer(ScannerFactory fac, CharBuffer buf) {
mcimadamore@1113 124 this(fac, new UnicodeReader(fac, buf));
mcimadamore@1113 125 }
mcimadamore@1113 126
mcimadamore@1113 127 protected JavaTokenizer(ScannerFactory fac, char[] buf, int inputLength) {
mcimadamore@1113 128 this(fac, new UnicodeReader(fac, buf, inputLength));
mcimadamore@1113 129 }
mcimadamore@1113 130
mcimadamore@1113 131 protected JavaTokenizer(ScannerFactory fac, UnicodeReader reader) {
mcimadamore@1113 132 log = fac.log;
mcimadamore@1113 133 names = fac.names;
mcimadamore@1113 134 tokens = fac.tokens;
mcimadamore@1113 135 source = fac.source;
mcimadamore@1113 136 this.reader = reader;
mcimadamore@1113 137 allowBinaryLiterals = source.allowBinaryLiterals();
mcimadamore@1113 138 allowHexFloats = source.allowHexFloats();
mcimadamore@1113 139 allowUnderscoresInLiterals = source.allowUnderscoresInLiterals();
mcimadamore@1113 140 }
mcimadamore@1113 141
mcimadamore@1113 142 /** Report an error at the given position using the provided arguments.
mcimadamore@1113 143 */
mcimadamore@1113 144 protected void lexError(int pos, String key, Object... args) {
mcimadamore@1113 145 log.error(pos, key, args);
mcimadamore@1113 146 tk = TokenKind.ERROR;
mcimadamore@1113 147 errPos = pos;
mcimadamore@1113 148 }
mcimadamore@1113 149
mcimadamore@1113 150 /** Read next character in comment, skipping over double '\' characters.
mcimadamore@1113 151 */
mcimadamore@1113 152 protected void scanCommentChar() {
mcimadamore@1113 153 reader.scanChar();
mcimadamore@1113 154 if (reader.ch == '\\') {
mcimadamore@1113 155 if (reader.peekChar() == '\\' && !reader.isUnicode()) {
mcimadamore@1113 156 reader.skipChar();
mcimadamore@1113 157 } else {
mcimadamore@1113 158 reader.convertUnicode();
mcimadamore@1113 159 }
mcimadamore@1113 160 }
mcimadamore@1113 161 }
mcimadamore@1113 162
mcimadamore@1113 163 /** Append a character to sbuf.
mcimadamore@1113 164 */
mcimadamore@1113 165 private void putChar(char ch) {
mcimadamore@1113 166 if (sp == sbuf.length) {
mcimadamore@1113 167 char[] newsbuf = new char[sbuf.length * 2];
mcimadamore@1113 168 System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
mcimadamore@1113 169 sbuf = newsbuf;
mcimadamore@1113 170 }
mcimadamore@1113 171 sbuf[sp++] = ch;
mcimadamore@1113 172 }
mcimadamore@1113 173
mcimadamore@1113 174 /** Read next character in character or string literal and copy into sbuf.
mcimadamore@1113 175 */
mcimadamore@1113 176 private void scanLitChar(int pos) {
mcimadamore@1113 177 if (reader.ch == '\\') {
mcimadamore@1113 178 if (reader.peekChar() == '\\' && !reader.isUnicode()) {
mcimadamore@1113 179 reader.skipChar();
mcimadamore@1113 180 putChar('\\');
mcimadamore@1113 181 reader.scanChar();
mcimadamore@1113 182 } else {
mcimadamore@1113 183 reader.scanChar();
mcimadamore@1113 184 switch (reader.ch) {
mcimadamore@1113 185 case '0': case '1': case '2': case '3':
mcimadamore@1113 186 case '4': case '5': case '6': case '7':
mcimadamore@1113 187 char leadch = reader.ch;
mcimadamore@1113 188 int oct = reader.digit(pos, 8);
mcimadamore@1113 189 reader.scanChar();
mcimadamore@1113 190 if ('0' <= reader.ch && reader.ch <= '7') {
mcimadamore@1113 191 oct = oct * 8 + reader.digit(pos, 8);
mcimadamore@1113 192 reader.scanChar();
mcimadamore@1113 193 if (leadch <= '3' && '0' <= reader.ch && reader.ch <= '7') {
mcimadamore@1113 194 oct = oct * 8 + reader.digit(pos, 8);
mcimadamore@1113 195 reader.scanChar();
mcimadamore@1113 196 }
mcimadamore@1113 197 }
mcimadamore@1113 198 putChar((char)oct);
mcimadamore@1113 199 break;
mcimadamore@1113 200 case 'b':
mcimadamore@1113 201 putChar('\b'); reader.scanChar(); break;
mcimadamore@1113 202 case 't':
mcimadamore@1113 203 putChar('\t'); reader.scanChar(); break;
mcimadamore@1113 204 case 'n':
mcimadamore@1113 205 putChar('\n'); reader.scanChar(); break;
mcimadamore@1113 206 case 'f':
mcimadamore@1113 207 putChar('\f'); reader.scanChar(); break;
mcimadamore@1113 208 case 'r':
mcimadamore@1113 209 putChar('\r'); reader.scanChar(); break;
mcimadamore@1113 210 case '\'':
mcimadamore@1113 211 putChar('\''); reader.scanChar(); break;
mcimadamore@1113 212 case '\"':
mcimadamore@1113 213 putChar('\"'); reader.scanChar(); break;
mcimadamore@1113 214 case '\\':
mcimadamore@1113 215 putChar('\\'); reader.scanChar(); break;
mcimadamore@1113 216 default:
mcimadamore@1113 217 lexError(reader.bp, "illegal.esc.char");
mcimadamore@1113 218 }
mcimadamore@1113 219 }
mcimadamore@1113 220 } else if (reader.bp != reader.buflen) {
mcimadamore@1113 221 putChar(reader.ch); reader.scanChar();
mcimadamore@1113 222 }
mcimadamore@1113 223 }
mcimadamore@1113 224
mcimadamore@1113 225 private void scanDigits(int pos, int digitRadix) {
mcimadamore@1113 226 char saveCh;
mcimadamore@1113 227 int savePos;
mcimadamore@1113 228 do {
mcimadamore@1113 229 if (reader.ch != '_') {
mcimadamore@1113 230 putChar(reader.ch);
mcimadamore@1113 231 } else {
mcimadamore@1113 232 if (!allowUnderscoresInLiterals) {
mcimadamore@1113 233 lexError(pos, "unsupported.underscore.lit", source.name);
mcimadamore@1113 234 allowUnderscoresInLiterals = true;
mcimadamore@1113 235 }
mcimadamore@1113 236 }
mcimadamore@1113 237 saveCh = reader.ch;
mcimadamore@1113 238 savePos = reader.bp;
mcimadamore@1113 239 reader.scanChar();
mcimadamore@1113 240 } while (reader.digit(pos, digitRadix) >= 0 || reader.ch == '_');
mcimadamore@1113 241 if (saveCh == '_')
mcimadamore@1113 242 lexError(savePos, "illegal.underscore");
mcimadamore@1113 243 }
mcimadamore@1113 244
mcimadamore@1113 245 /** Read fractional part of hexadecimal floating point number.
mcimadamore@1113 246 */
mcimadamore@1113 247 private void scanHexExponentAndSuffix(int pos) {
mcimadamore@1113 248 if (reader.ch == 'p' || reader.ch == 'P') {
mcimadamore@1113 249 putChar(reader.ch);
mcimadamore@1113 250 reader.scanChar();
mcimadamore@1113 251 skipIllegalUnderscores();
mcimadamore@1113 252 if (reader.ch == '+' || reader.ch == '-') {
mcimadamore@1113 253 putChar(reader.ch);
mcimadamore@1113 254 reader.scanChar();
mcimadamore@1113 255 }
mcimadamore@1113 256 skipIllegalUnderscores();
mcimadamore@1113 257 if ('0' <= reader.ch && reader.ch <= '9') {
mcimadamore@1113 258 scanDigits(pos, 10);
mcimadamore@1113 259 if (!allowHexFloats) {
mcimadamore@1113 260 lexError(pos, "unsupported.fp.lit", source.name);
mcimadamore@1113 261 allowHexFloats = true;
mcimadamore@1113 262 }
mcimadamore@1113 263 else if (!hexFloatsWork)
mcimadamore@1113 264 lexError(pos, "unsupported.cross.fp.lit");
mcimadamore@1113 265 } else
mcimadamore@1113 266 lexError(pos, "malformed.fp.lit");
mcimadamore@1113 267 } else {
mcimadamore@1113 268 lexError(pos, "malformed.fp.lit");
mcimadamore@1113 269 }
mcimadamore@1113 270 if (reader.ch == 'f' || reader.ch == 'F') {
mcimadamore@1113 271 putChar(reader.ch);
mcimadamore@1113 272 reader.scanChar();
mcimadamore@1113 273 tk = TokenKind.FLOATLITERAL;
mcimadamore@1113 274 radix = 16;
mcimadamore@1113 275 } else {
mcimadamore@1113 276 if (reader.ch == 'd' || reader.ch == 'D') {
mcimadamore@1113 277 putChar(reader.ch);
mcimadamore@1113 278 reader.scanChar();
mcimadamore@1113 279 }
mcimadamore@1113 280 tk = TokenKind.DOUBLELITERAL;
mcimadamore@1113 281 radix = 16;
mcimadamore@1113 282 }
mcimadamore@1113 283 }
mcimadamore@1113 284
mcimadamore@1113 285 /** Read fractional part of floating point number.
mcimadamore@1113 286 */
mcimadamore@1113 287 private void scanFraction(int pos) {
mcimadamore@1113 288 skipIllegalUnderscores();
mcimadamore@1113 289 if ('0' <= reader.ch && reader.ch <= '9') {
mcimadamore@1113 290 scanDigits(pos, 10);
mcimadamore@1113 291 }
mcimadamore@1113 292 int sp1 = sp;
mcimadamore@1113 293 if (reader.ch == 'e' || reader.ch == 'E') {
mcimadamore@1113 294 putChar(reader.ch);
mcimadamore@1113 295 reader.scanChar();
mcimadamore@1113 296 skipIllegalUnderscores();
mcimadamore@1113 297 if (reader.ch == '+' || reader.ch == '-') {
mcimadamore@1113 298 putChar(reader.ch);
mcimadamore@1113 299 reader.scanChar();
mcimadamore@1113 300 }
mcimadamore@1113 301 skipIllegalUnderscores();
mcimadamore@1113 302 if ('0' <= reader.ch && reader.ch <= '9') {
mcimadamore@1113 303 scanDigits(pos, 10);
mcimadamore@1113 304 return;
mcimadamore@1113 305 }
mcimadamore@1113 306 lexError(pos, "malformed.fp.lit");
mcimadamore@1113 307 sp = sp1;
mcimadamore@1113 308 }
mcimadamore@1113 309 }
mcimadamore@1113 310
mcimadamore@1113 311 /** Read fractional part and 'd' or 'f' suffix of floating point number.
mcimadamore@1113 312 */
mcimadamore@1113 313 private void scanFractionAndSuffix(int pos) {
mcimadamore@1113 314 radix = 10;
mcimadamore@1113 315 scanFraction(pos);
mcimadamore@1113 316 if (reader.ch == 'f' || reader.ch == 'F') {
mcimadamore@1113 317 putChar(reader.ch);
mcimadamore@1113 318 reader.scanChar();
mcimadamore@1113 319 tk = TokenKind.FLOATLITERAL;
mcimadamore@1113 320 } else {
mcimadamore@1113 321 if (reader.ch == 'd' || reader.ch == 'D') {
mcimadamore@1113 322 putChar(reader.ch);
mcimadamore@1113 323 reader.scanChar();
mcimadamore@1113 324 }
mcimadamore@1113 325 tk = TokenKind.DOUBLELITERAL;
mcimadamore@1113 326 }
mcimadamore@1113 327 }
mcimadamore@1113 328
mcimadamore@1113 329 /** Read fractional part and 'd' or 'f' suffix of floating point number.
mcimadamore@1113 330 */
mcimadamore@1113 331 private void scanHexFractionAndSuffix(int pos, boolean seendigit) {
mcimadamore@1113 332 radix = 16;
mcimadamore@1113 333 Assert.check(reader.ch == '.');
mcimadamore@1113 334 putChar(reader.ch);
mcimadamore@1113 335 reader.scanChar();
mcimadamore@1113 336 skipIllegalUnderscores();
mcimadamore@1113 337 if (reader.digit(pos, 16) >= 0) {
mcimadamore@1113 338 seendigit = true;
mcimadamore@1113 339 scanDigits(pos, 16);
mcimadamore@1113 340 }
mcimadamore@1113 341 if (!seendigit)
mcimadamore@1113 342 lexError(pos, "invalid.hex.number");
mcimadamore@1113 343 else
mcimadamore@1113 344 scanHexExponentAndSuffix(pos);
mcimadamore@1113 345 }
mcimadamore@1113 346
mcimadamore@1113 347 private void skipIllegalUnderscores() {
mcimadamore@1113 348 if (reader.ch == '_') {
mcimadamore@1113 349 lexError(reader.bp, "illegal.underscore");
mcimadamore@1113 350 while (reader.ch == '_')
mcimadamore@1113 351 reader.scanChar();
mcimadamore@1113 352 }
mcimadamore@1113 353 }
mcimadamore@1113 354
mcimadamore@1113 355 /** Read a number.
mcimadamore@1113 356 * @param radix The radix of the number; one of 2, j8, 10, 16.
mcimadamore@1113 357 */
mcimadamore@1113 358 private void scanNumber(int pos, int radix) {
mcimadamore@1113 359 // for octal, allow base-10 digit in case it's a float literal
mcimadamore@1113 360 this.radix = radix;
mcimadamore@1113 361 int digitRadix = (radix == 8 ? 10 : radix);
mcimadamore@1113 362 boolean seendigit = false;
mcimadamore@1113 363 if (reader.digit(pos, digitRadix) >= 0) {
mcimadamore@1113 364 seendigit = true;
mcimadamore@1113 365 scanDigits(pos, digitRadix);
mcimadamore@1113 366 }
mcimadamore@1113 367 if (radix == 16 && reader.ch == '.') {
mcimadamore@1113 368 scanHexFractionAndSuffix(pos, seendigit);
mcimadamore@1113 369 } else if (seendigit && radix == 16 && (reader.ch == 'p' || reader.ch == 'P')) {
mcimadamore@1113 370 scanHexExponentAndSuffix(pos);
mcimadamore@1113 371 } else if (digitRadix == 10 && reader.ch == '.') {
mcimadamore@1113 372 putChar(reader.ch);
mcimadamore@1113 373 reader.scanChar();
mcimadamore@1113 374 scanFractionAndSuffix(pos);
mcimadamore@1113 375 } else if (digitRadix == 10 &&
mcimadamore@1113 376 (reader.ch == 'e' || reader.ch == 'E' ||
mcimadamore@1113 377 reader.ch == 'f' || reader.ch == 'F' ||
mcimadamore@1113 378 reader.ch == 'd' || reader.ch == 'D')) {
mcimadamore@1113 379 scanFractionAndSuffix(pos);
mcimadamore@1113 380 } else {
mcimadamore@1113 381 if (reader.ch == 'l' || reader.ch == 'L') {
mcimadamore@1113 382 reader.scanChar();
mcimadamore@1113 383 tk = TokenKind.LONGLITERAL;
mcimadamore@1113 384 } else {
mcimadamore@1113 385 tk = TokenKind.INTLITERAL;
mcimadamore@1113 386 }
mcimadamore@1113 387 }
mcimadamore@1113 388 }
mcimadamore@1113 389
mcimadamore@1113 390 /** Read an identifier.
mcimadamore@1113 391 */
mcimadamore@1113 392 private void scanIdent() {
mcimadamore@1113 393 boolean isJavaIdentifierPart;
mcimadamore@1113 394 char high;
mcimadamore@1113 395 do {
mcimadamore@1113 396 if (sp == sbuf.length) putChar(reader.ch); else sbuf[sp++] = reader.ch;
mcimadamore@1113 397 // optimization, was: putChar(reader.ch);
mcimadamore@1113 398
mcimadamore@1113 399 reader.scanChar();
mcimadamore@1113 400 switch (reader.ch) {
mcimadamore@1113 401 case 'A': case 'B': case 'C': case 'D': case 'E':
mcimadamore@1113 402 case 'F': case 'G': case 'H': case 'I': case 'J':
mcimadamore@1113 403 case 'K': case 'L': case 'M': case 'N': case 'O':
mcimadamore@1113 404 case 'P': case 'Q': case 'R': case 'S': case 'T':
mcimadamore@1113 405 case 'U': case 'V': case 'W': case 'X': case 'Y':
mcimadamore@1113 406 case 'Z':
mcimadamore@1113 407 case 'a': case 'b': case 'c': case 'd': case 'e':
mcimadamore@1113 408 case 'f': case 'g': case 'h': case 'i': case 'j':
mcimadamore@1113 409 case 'k': case 'l': case 'm': case 'n': case 'o':
mcimadamore@1113 410 case 'p': case 'q': case 'r': case 's': case 't':
mcimadamore@1113 411 case 'u': case 'v': case 'w': case 'x': case 'y':
mcimadamore@1113 412 case 'z':
mcimadamore@1113 413 case '$': case '_':
mcimadamore@1113 414 case '0': case '1': case '2': case '3': case '4':
mcimadamore@1113 415 case '5': case '6': case '7': case '8': case '9':
mcimadamore@1113 416 case '\u0000': case '\u0001': case '\u0002': case '\u0003':
mcimadamore@1113 417 case '\u0004': case '\u0005': case '\u0006': case '\u0007':
mcimadamore@1113 418 case '\u0008': case '\u000E': case '\u000F': case '\u0010':
mcimadamore@1113 419 case '\u0011': case '\u0012': case '\u0013': case '\u0014':
mcimadamore@1113 420 case '\u0015': case '\u0016': case '\u0017':
mcimadamore@1113 421 case '\u0018': case '\u0019': case '\u001B':
mcimadamore@1113 422 case '\u007F':
mcimadamore@1113 423 break;
mcimadamore@1113 424 case '\u001A': // EOI is also a legal identifier part
mcimadamore@1113 425 if (reader.bp >= reader.buflen) {
mcimadamore@1113 426 name = names.fromChars(sbuf, 0, sp);
mcimadamore@1113 427 tk = tokens.lookupKind(name);
mcimadamore@1113 428 return;
mcimadamore@1113 429 }
mcimadamore@1113 430 break;
mcimadamore@1113 431 default:
mcimadamore@1113 432 if (reader.ch < '\u0080') {
mcimadamore@1113 433 // all ASCII range chars already handled, above
mcimadamore@1113 434 isJavaIdentifierPart = false;
mcimadamore@1113 435 } else {
mcimadamore@1113 436 high = reader.scanSurrogates();
mcimadamore@1113 437 if (high != 0) {
mcimadamore@1113 438 if (sp == sbuf.length) {
mcimadamore@1113 439 putChar(high);
mcimadamore@1113 440 } else {
mcimadamore@1113 441 sbuf[sp++] = high;
mcimadamore@1113 442 }
mcimadamore@1113 443 isJavaIdentifierPart = Character.isJavaIdentifierPart(
mcimadamore@1113 444 Character.toCodePoint(high, reader.ch));
mcimadamore@1113 445 } else {
mcimadamore@1113 446 isJavaIdentifierPart = Character.isJavaIdentifierPart(reader.ch);
mcimadamore@1113 447 }
mcimadamore@1113 448 }
mcimadamore@1113 449 if (!isJavaIdentifierPart) {
mcimadamore@1113 450 name = names.fromChars(sbuf, 0, sp);
mcimadamore@1113 451 tk = tokens.lookupKind(name);
mcimadamore@1113 452 return;
mcimadamore@1113 453 }
mcimadamore@1113 454 }
mcimadamore@1113 455 } while (true);
mcimadamore@1113 456 }
mcimadamore@1113 457
mcimadamore@1113 458 /** Return true if reader.ch can be part of an operator.
mcimadamore@1113 459 */
mcimadamore@1113 460 private boolean isSpecial(char ch) {
mcimadamore@1113 461 switch (ch) {
mcimadamore@1113 462 case '!': case '%': case '&': case '*': case '?':
mcimadamore@1113 463 case '+': case '-': case ':': case '<': case '=':
mcimadamore@1113 464 case '>': case '^': case '|': case '~':
mcimadamore@1113 465 case '@':
mcimadamore@1113 466 return true;
mcimadamore@1113 467 default:
mcimadamore@1113 468 return false;
mcimadamore@1113 469 }
mcimadamore@1113 470 }
mcimadamore@1113 471
mcimadamore@1113 472 /** Read longest possible sequence of special characters and convert
mcimadamore@1113 473 * to token.
mcimadamore@1113 474 */
mcimadamore@1113 475 private void scanOperator() {
mcimadamore@1113 476 while (true) {
mcimadamore@1113 477 putChar(reader.ch);
mcimadamore@1113 478 Name newname = names.fromChars(sbuf, 0, sp);
mcimadamore@1113 479 TokenKind tk1 = tokens.lookupKind(newname);
mcimadamore@1113 480 if (tk1 == TokenKind.IDENTIFIER) {
mcimadamore@1113 481 sp--;
mcimadamore@1113 482 break;
mcimadamore@1113 483 }
mcimadamore@1113 484 tk = tk1;
mcimadamore@1113 485 reader.scanChar();
mcimadamore@1113 486 if (!isSpecial(reader.ch)) break;
mcimadamore@1113 487 }
mcimadamore@1113 488 }
mcimadamore@1113 489
mcimadamore@1113 490 /**
mcimadamore@1113 491 * Scan a documentation comment; determine if a deprecated tag is present.
mcimadamore@1113 492 * Called once the initial /, * have been skipped, positioned at the second *
mcimadamore@1113 493 * (which is treated as the beginning of the first line).
mcimadamore@1113 494 * Stops positioned at the closing '/'.
mcimadamore@1113 495 */
mcimadamore@1113 496 @SuppressWarnings("fallthrough")
mcimadamore@1113 497 private void scanDocComment() {
mcimadamore@1113 498 boolean deprecatedPrefix = false;
mcimadamore@1113 499
mcimadamore@1113 500 forEachLine:
mcimadamore@1113 501 while (reader.bp < reader.buflen) {
mcimadamore@1113 502
mcimadamore@1113 503 // Skip optional WhiteSpace at beginning of line
mcimadamore@1113 504 while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) {
mcimadamore@1113 505 scanCommentChar();
mcimadamore@1113 506 }
mcimadamore@1113 507
mcimadamore@1113 508 // Skip optional consecutive Stars
mcimadamore@1113 509 while (reader.bp < reader.buflen && reader.ch == '*') {
mcimadamore@1113 510 scanCommentChar();
mcimadamore@1113 511 if (reader.ch == '/') {
mcimadamore@1113 512 return;
mcimadamore@1113 513 }
mcimadamore@1113 514 }
mcimadamore@1113 515
mcimadamore@1113 516 // Skip optional WhiteSpace after Stars
mcimadamore@1113 517 while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) {
mcimadamore@1113 518 scanCommentChar();
mcimadamore@1113 519 }
mcimadamore@1113 520
mcimadamore@1113 521 deprecatedPrefix = false;
mcimadamore@1113 522 // At beginning of line in the JavaDoc sense.
mcimadamore@1113 523 if (reader.bp < reader.buflen && reader.ch == '@' && !deprecatedFlag) {
mcimadamore@1113 524 scanCommentChar();
mcimadamore@1113 525 if (reader.bp < reader.buflen && reader.ch == 'd') {
mcimadamore@1113 526 scanCommentChar();
mcimadamore@1113 527 if (reader.bp < reader.buflen && reader.ch == 'e') {
mcimadamore@1113 528 scanCommentChar();
mcimadamore@1113 529 if (reader.bp < reader.buflen && reader.ch == 'p') {
mcimadamore@1113 530 scanCommentChar();
mcimadamore@1113 531 if (reader.bp < reader.buflen && reader.ch == 'r') {
mcimadamore@1113 532 scanCommentChar();
mcimadamore@1113 533 if (reader.bp < reader.buflen && reader.ch == 'e') {
mcimadamore@1113 534 scanCommentChar();
mcimadamore@1113 535 if (reader.bp < reader.buflen && reader.ch == 'c') {
mcimadamore@1113 536 scanCommentChar();
mcimadamore@1113 537 if (reader.bp < reader.buflen && reader.ch == 'a') {
mcimadamore@1113 538 scanCommentChar();
mcimadamore@1113 539 if (reader.bp < reader.buflen && reader.ch == 't') {
mcimadamore@1113 540 scanCommentChar();
mcimadamore@1113 541 if (reader.bp < reader.buflen && reader.ch == 'e') {
mcimadamore@1113 542 scanCommentChar();
mcimadamore@1113 543 if (reader.bp < reader.buflen && reader.ch == 'd') {
mcimadamore@1113 544 deprecatedPrefix = true;
mcimadamore@1113 545 scanCommentChar();
mcimadamore@1113 546 }}}}}}}}}}}
mcimadamore@1113 547 if (deprecatedPrefix && reader.bp < reader.buflen) {
mcimadamore@1113 548 if (Character.isWhitespace(reader.ch)) {
mcimadamore@1113 549 deprecatedFlag = true;
mcimadamore@1113 550 } else if (reader.ch == '*') {
mcimadamore@1113 551 scanCommentChar();
mcimadamore@1113 552 if (reader.ch == '/') {
mcimadamore@1113 553 deprecatedFlag = true;
mcimadamore@1113 554 return;
mcimadamore@1113 555 }
mcimadamore@1113 556 }
mcimadamore@1113 557 }
mcimadamore@1113 558
mcimadamore@1113 559 // Skip rest of line
mcimadamore@1113 560 while (reader.bp < reader.buflen) {
mcimadamore@1113 561 switch (reader.ch) {
mcimadamore@1113 562 case '*':
mcimadamore@1113 563 scanCommentChar();
mcimadamore@1113 564 if (reader.ch == '/') {
mcimadamore@1113 565 return;
mcimadamore@1113 566 }
mcimadamore@1113 567 break;
mcimadamore@1113 568 case CR: // (Spec 3.4)
mcimadamore@1113 569 scanCommentChar();
mcimadamore@1113 570 if (reader.ch != LF) {
mcimadamore@1113 571 continue forEachLine;
mcimadamore@1113 572 }
mcimadamore@1113 573 /* fall through to LF case */
mcimadamore@1113 574 case LF: // (Spec 3.4)
mcimadamore@1113 575 scanCommentChar();
mcimadamore@1113 576 continue forEachLine;
mcimadamore@1113 577 default:
mcimadamore@1113 578 scanCommentChar();
mcimadamore@1113 579 }
mcimadamore@1113 580 } // rest of line
mcimadamore@1113 581 } // forEachLine
mcimadamore@1113 582 return;
mcimadamore@1113 583 }
mcimadamore@1113 584
mcimadamore@1113 585 /** Read token.
mcimadamore@1113 586 */
mcimadamore@1113 587 public Token readToken() {
mcimadamore@1113 588
mcimadamore@1113 589 sp = 0;
mcimadamore@1113 590 name = null;
mcimadamore@1113 591 deprecatedFlag = false;
mcimadamore@1113 592 radix = 0;
mcimadamore@1113 593 int pos = 0;
mcimadamore@1113 594 int endPos = 0;
mcimadamore@1113 595
mcimadamore@1113 596 try {
mcimadamore@1113 597 loop: while (true) {
mcimadamore@1113 598 pos = reader.bp;
mcimadamore@1113 599 switch (reader.ch) {
mcimadamore@1113 600 case ' ': // (Spec 3.6)
mcimadamore@1113 601 case '\t': // (Spec 3.6)
mcimadamore@1113 602 case FF: // (Spec 3.6)
mcimadamore@1113 603 do {
mcimadamore@1113 604 reader.scanChar();
mcimadamore@1113 605 } while (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF);
mcimadamore@1113 606 processWhiteSpace(pos, reader.bp);
mcimadamore@1113 607 break;
mcimadamore@1113 608 case LF: // (Spec 3.4)
mcimadamore@1113 609 reader.scanChar();
mcimadamore@1113 610 processLineTerminator(pos, reader.bp);
mcimadamore@1113 611 break;
mcimadamore@1113 612 case CR: // (Spec 3.4)
mcimadamore@1113 613 reader.scanChar();
mcimadamore@1113 614 if (reader.ch == LF) {
mcimadamore@1113 615 reader.scanChar();
mcimadamore@1113 616 }
mcimadamore@1113 617 processLineTerminator(pos, reader.bp);
mcimadamore@1113 618 break;
mcimadamore@1113 619 case 'A': case 'B': case 'C': case 'D': case 'E':
mcimadamore@1113 620 case 'F': case 'G': case 'H': case 'I': case 'J':
mcimadamore@1113 621 case 'K': case 'L': case 'M': case 'N': case 'O':
mcimadamore@1113 622 case 'P': case 'Q': case 'R': case 'S': case 'T':
mcimadamore@1113 623 case 'U': case 'V': case 'W': case 'X': case 'Y':
mcimadamore@1113 624 case 'Z':
mcimadamore@1113 625 case 'a': case 'b': case 'c': case 'd': case 'e':
mcimadamore@1113 626 case 'f': case 'g': case 'h': case 'i': case 'j':
mcimadamore@1113 627 case 'k': case 'l': case 'm': case 'n': case 'o':
mcimadamore@1113 628 case 'p': case 'q': case 'r': case 's': case 't':
mcimadamore@1113 629 case 'u': case 'v': case 'w': case 'x': case 'y':
mcimadamore@1113 630 case 'z':
mcimadamore@1113 631 case '$': case '_':
mcimadamore@1113 632 scanIdent();
mcimadamore@1113 633 break loop;
mcimadamore@1113 634 case '0':
mcimadamore@1113 635 reader.scanChar();
mcimadamore@1113 636 if (reader.ch == 'x' || reader.ch == 'X') {
mcimadamore@1113 637 reader.scanChar();
mcimadamore@1113 638 skipIllegalUnderscores();
mcimadamore@1113 639 if (reader.ch == '.') {
mcimadamore@1113 640 scanHexFractionAndSuffix(pos, false);
mcimadamore@1113 641 } else if (reader.digit(pos, 16) < 0) {
mcimadamore@1113 642 lexError(pos, "invalid.hex.number");
mcimadamore@1113 643 } else {
mcimadamore@1113 644 scanNumber(pos, 16);
mcimadamore@1113 645 }
mcimadamore@1113 646 } else if (reader.ch == 'b' || reader.ch == 'B') {
mcimadamore@1113 647 if (!allowBinaryLiterals) {
mcimadamore@1113 648 lexError(pos, "unsupported.binary.lit", source.name);
mcimadamore@1113 649 allowBinaryLiterals = true;
mcimadamore@1113 650 }
mcimadamore@1113 651 reader.scanChar();
mcimadamore@1113 652 skipIllegalUnderscores();
mcimadamore@1113 653 if (reader.digit(pos, 2) < 0) {
mcimadamore@1113 654 lexError(pos, "invalid.binary.number");
mcimadamore@1113 655 } else {
mcimadamore@1113 656 scanNumber(pos, 2);
mcimadamore@1113 657 }
mcimadamore@1113 658 } else {
mcimadamore@1113 659 putChar('0');
mcimadamore@1113 660 if (reader.ch == '_') {
mcimadamore@1113 661 int savePos = reader.bp;
mcimadamore@1113 662 do {
mcimadamore@1113 663 reader.scanChar();
mcimadamore@1113 664 } while (reader.ch == '_');
mcimadamore@1113 665 if (reader.digit(pos, 10) < 0) {
mcimadamore@1113 666 lexError(savePos, "illegal.underscore");
mcimadamore@1113 667 }
mcimadamore@1113 668 }
mcimadamore@1113 669 scanNumber(pos, 8);
mcimadamore@1113 670 }
mcimadamore@1113 671 break loop;
mcimadamore@1113 672 case '1': case '2': case '3': case '4':
mcimadamore@1113 673 case '5': case '6': case '7': case '8': case '9':
mcimadamore@1113 674 scanNumber(pos, 10);
mcimadamore@1113 675 break loop;
mcimadamore@1113 676 case '.':
mcimadamore@1113 677 reader.scanChar();
mcimadamore@1113 678 if ('0' <= reader.ch && reader.ch <= '9') {
mcimadamore@1113 679 putChar('.');
mcimadamore@1113 680 scanFractionAndSuffix(pos);
mcimadamore@1113 681 } else if (reader.ch == '.') {
mcimadamore@1113 682 putChar('.'); putChar('.');
mcimadamore@1113 683 reader.scanChar();
mcimadamore@1113 684 if (reader.ch == '.') {
mcimadamore@1113 685 reader.scanChar();
mcimadamore@1113 686 putChar('.');
mcimadamore@1113 687 tk = TokenKind.ELLIPSIS;
mcimadamore@1113 688 } else {
mcimadamore@1113 689 lexError(pos, "malformed.fp.lit");
mcimadamore@1113 690 }
mcimadamore@1113 691 } else {
mcimadamore@1113 692 tk = TokenKind.DOT;
mcimadamore@1113 693 }
mcimadamore@1113 694 break loop;
mcimadamore@1113 695 case ',':
mcimadamore@1113 696 reader.scanChar(); tk = TokenKind.COMMA; break loop;
mcimadamore@1113 697 case ';':
mcimadamore@1113 698 reader.scanChar(); tk = TokenKind.SEMI; break loop;
mcimadamore@1113 699 case '(':
mcimadamore@1113 700 reader.scanChar(); tk = TokenKind.LPAREN; break loop;
mcimadamore@1113 701 case ')':
mcimadamore@1113 702 reader.scanChar(); tk = TokenKind.RPAREN; break loop;
mcimadamore@1113 703 case '[':
mcimadamore@1113 704 reader.scanChar(); tk = TokenKind.LBRACKET; break loop;
mcimadamore@1113 705 case ']':
mcimadamore@1113 706 reader.scanChar(); tk = TokenKind.RBRACKET; break loop;
mcimadamore@1113 707 case '{':
mcimadamore@1113 708 reader.scanChar(); tk = TokenKind.LBRACE; break loop;
mcimadamore@1113 709 case '}':
mcimadamore@1113 710 reader.scanChar(); tk = TokenKind.RBRACE; break loop;
mcimadamore@1113 711 case '/':
mcimadamore@1113 712 reader.scanChar();
mcimadamore@1113 713 if (reader.ch == '/') {
mcimadamore@1113 714 do {
mcimadamore@1113 715 scanCommentChar();
mcimadamore@1113 716 } while (reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen);
mcimadamore@1113 717 if (reader.bp < reader.buflen) {
mcimadamore@1113 718 processComment(pos, reader.bp, CommentStyle.LINE);
mcimadamore@1113 719 }
mcimadamore@1113 720 break;
mcimadamore@1113 721 } else if (reader.ch == '*') {
mcimadamore@1113 722 reader.scanChar();
mcimadamore@1113 723 CommentStyle style;
mcimadamore@1113 724 if (reader.ch == '*') {
mcimadamore@1113 725 style = CommentStyle.JAVADOC;
mcimadamore@1113 726 scanDocComment();
mcimadamore@1113 727 } else {
mcimadamore@1113 728 style = CommentStyle.BLOCK;
mcimadamore@1113 729 while (reader.bp < reader.buflen) {
mcimadamore@1113 730 if (reader.ch == '*') {
mcimadamore@1113 731 reader.scanChar();
mcimadamore@1113 732 if (reader.ch == '/') break;
mcimadamore@1113 733 } else {
mcimadamore@1113 734 scanCommentChar();
mcimadamore@1113 735 }
mcimadamore@1113 736 }
mcimadamore@1113 737 }
mcimadamore@1113 738 if (reader.ch == '/') {
mcimadamore@1113 739 reader.scanChar();
mcimadamore@1113 740 processComment(pos, reader.bp, style);
mcimadamore@1113 741 break;
mcimadamore@1113 742 } else {
mcimadamore@1113 743 lexError(pos, "unclosed.comment");
mcimadamore@1113 744 break loop;
mcimadamore@1113 745 }
mcimadamore@1113 746 } else if (reader.ch == '=') {
mcimadamore@1113 747 tk = TokenKind.SLASHEQ;
mcimadamore@1113 748 reader.scanChar();
mcimadamore@1113 749 } else {
mcimadamore@1113 750 tk = TokenKind.SLASH;
mcimadamore@1113 751 }
mcimadamore@1113 752 break loop;
mcimadamore@1113 753 case '\'':
mcimadamore@1113 754 reader.scanChar();
mcimadamore@1113 755 if (reader.ch == '\'') {
mcimadamore@1113 756 lexError(pos, "empty.char.lit");
mcimadamore@1113 757 } else {
mcimadamore@1113 758 if (reader.ch == CR || reader.ch == LF)
mcimadamore@1113 759 lexError(pos, "illegal.line.end.in.char.lit");
mcimadamore@1113 760 scanLitChar(pos);
mcimadamore@1113 761 char ch2 = reader.ch;
mcimadamore@1113 762 if (reader.ch == '\'') {
mcimadamore@1113 763 reader.scanChar();
mcimadamore@1113 764 tk = TokenKind.CHARLITERAL;
mcimadamore@1113 765 } else {
mcimadamore@1113 766 lexError(pos, "unclosed.char.lit");
mcimadamore@1113 767 }
mcimadamore@1113 768 }
mcimadamore@1113 769 break loop;
mcimadamore@1113 770 case '\"':
mcimadamore@1113 771 reader.scanChar();
mcimadamore@1113 772 while (reader.ch != '\"' && reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen)
mcimadamore@1113 773 scanLitChar(pos);
mcimadamore@1113 774 if (reader.ch == '\"') {
mcimadamore@1113 775 tk = TokenKind.STRINGLITERAL;
mcimadamore@1113 776 reader.scanChar();
mcimadamore@1113 777 } else {
mcimadamore@1113 778 lexError(pos, "unclosed.str.lit");
mcimadamore@1113 779 }
mcimadamore@1113 780 break loop;
mcimadamore@1113 781 default:
mcimadamore@1113 782 if (isSpecial(reader.ch)) {
mcimadamore@1113 783 scanOperator();
mcimadamore@1113 784 } else {
mcimadamore@1113 785 boolean isJavaIdentifierStart;
mcimadamore@1113 786 if (reader.ch < '\u0080') {
mcimadamore@1113 787 // all ASCII range chars already handled, above
mcimadamore@1113 788 isJavaIdentifierStart = false;
mcimadamore@1113 789 } else {
mcimadamore@1113 790 char high = reader.scanSurrogates();
mcimadamore@1113 791 if (high != 0) {
mcimadamore@1113 792 if (sp == sbuf.length) {
mcimadamore@1113 793 putChar(high);
mcimadamore@1113 794 } else {
mcimadamore@1113 795 sbuf[sp++] = high;
mcimadamore@1113 796 }
mcimadamore@1113 797
mcimadamore@1113 798 isJavaIdentifierStart = Character.isJavaIdentifierStart(
mcimadamore@1113 799 Character.toCodePoint(high, reader.ch));
mcimadamore@1113 800 } else {
mcimadamore@1113 801 isJavaIdentifierStart = Character.isJavaIdentifierStart(reader.ch);
mcimadamore@1113 802 }
mcimadamore@1113 803 }
mcimadamore@1113 804 if (isJavaIdentifierStart) {
mcimadamore@1113 805 scanIdent();
mcimadamore@1113 806 } else if (reader.bp == reader.buflen || reader.ch == EOI && reader.bp + 1 == reader.buflen) { // JLS 3.5
mcimadamore@1113 807 tk = TokenKind.EOF;
mcimadamore@1113 808 pos = reader.buflen;
mcimadamore@1113 809 } else {
mcimadamore@1113 810 lexError(pos, "illegal.char", String.valueOf((int)reader.ch));
mcimadamore@1113 811 reader.scanChar();
mcimadamore@1113 812 }
mcimadamore@1113 813 }
mcimadamore@1113 814 break loop;
mcimadamore@1113 815 }
mcimadamore@1113 816 }
mcimadamore@1113 817 endPos = reader.bp;
mcimadamore@1113 818 switch (tk.tag) {
mcimadamore@1113 819 case DEFAULT: return new Token(tk, pos, endPos, deprecatedFlag);
mcimadamore@1113 820 case NAMED: return new NamedToken(tk, pos, endPos, name, deprecatedFlag);
mcimadamore@1113 821 case STRING: return new StringToken(tk, pos, endPos, new String(sbuf, 0, sp), deprecatedFlag);
mcimadamore@1113 822 case NUMERIC: return new NumericToken(tk, pos, endPos, new String(sbuf, 0, sp), radix, deprecatedFlag);
mcimadamore@1113 823 default: throw new AssertionError();
mcimadamore@1113 824 }
mcimadamore@1113 825 }
mcimadamore@1113 826 finally {
mcimadamore@1113 827 if (scannerDebug) {
mcimadamore@1113 828 System.out.println("nextToken(" + pos
mcimadamore@1113 829 + "," + endPos + ")=|" +
mcimadamore@1113 830 new String(reader.getRawCharacters(pos, endPos))
mcimadamore@1113 831 + "|");
mcimadamore@1113 832 }
mcimadamore@1113 833 }
mcimadamore@1113 834 }
mcimadamore@1113 835
mcimadamore@1113 836 /** Return the position where a lexical error occurred;
mcimadamore@1113 837 */
mcimadamore@1113 838 public int errPos() {
mcimadamore@1113 839 return errPos;
mcimadamore@1113 840 }
mcimadamore@1113 841
mcimadamore@1113 842 /** Set the position where a lexical error occurred;
mcimadamore@1113 843 */
mcimadamore@1113 844 public void errPos(int pos) {
mcimadamore@1113 845 errPos = pos;
mcimadamore@1113 846 }
mcimadamore@1113 847
mcimadamore@1113 848 public enum CommentStyle {
mcimadamore@1113 849 LINE,
mcimadamore@1113 850 BLOCK,
mcimadamore@1113 851 JAVADOC,
mcimadamore@1113 852 }
mcimadamore@1113 853
mcimadamore@1113 854 /**
mcimadamore@1113 855 * Called when a complete comment has been scanned. pos and endPos
mcimadamore@1113 856 * will mark the comment boundary.
mcimadamore@1113 857 */
mcimadamore@1113 858 protected void processComment(int pos, int endPos, CommentStyle style) {
mcimadamore@1113 859 if (scannerDebug)
mcimadamore@1113 860 System.out.println("processComment(" + pos
mcimadamore@1113 861 + "," + endPos + "," + style + ")=|"
mcimadamore@1113 862 + new String(reader.getRawCharacters(pos, endPos))
mcimadamore@1113 863 + "|");
mcimadamore@1113 864 }
mcimadamore@1113 865
mcimadamore@1113 866 /**
mcimadamore@1113 867 * Called when a complete whitespace run has been scanned. pos and endPos
mcimadamore@1113 868 * will mark the whitespace boundary.
mcimadamore@1113 869 */
mcimadamore@1113 870 protected void processWhiteSpace(int pos, int endPos) {
mcimadamore@1113 871 if (scannerDebug)
mcimadamore@1113 872 System.out.println("processWhitespace(" + pos
mcimadamore@1113 873 + "," + endPos + ")=|" +
mcimadamore@1113 874 new String(reader.getRawCharacters(pos, endPos))
mcimadamore@1113 875 + "|");
mcimadamore@1113 876 }
mcimadamore@1113 877
mcimadamore@1113 878 /**
mcimadamore@1113 879 * Called when a line terminator has been processed.
mcimadamore@1113 880 */
mcimadamore@1113 881 protected void processLineTerminator(int pos, int endPos) {
mcimadamore@1113 882 if (scannerDebug)
mcimadamore@1113 883 System.out.println("processTerminator(" + pos
mcimadamore@1113 884 + "," + endPos + ")=|" +
mcimadamore@1113 885 new String(reader.getRawCharacters(pos, endPos))
mcimadamore@1113 886 + "|");
mcimadamore@1113 887 }
mcimadamore@1113 888
mcimadamore@1113 889 /** Build a map for translating between line numbers and
mcimadamore@1113 890 * positions in the input.
mcimadamore@1113 891 *
mcimadamore@1113 892 * @return a LineMap */
mcimadamore@1113 893 public Position.LineMap getLineMap() {
mcimadamore@1113 894 return Position.makeLineMap(reader.getRawCharacters(), reader.buflen, false);
mcimadamore@1113 895 }
mcimadamore@1113 896 }

mercurial