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

Mon, 10 Dec 2012 16:21:26 +0000

author
vromero
date
Mon, 10 Dec 2012 16:21:26 +0000
changeset 1442
fcf89720ae71
parent 1431
1f41a5758cf7
child 1679
b402b93cbe38
permissions
-rw-r--r--

8003967: detect and remove all mutable implicit static enum fields in langtools
Reviewed-by: jjg

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

mercurial