494 case 25: case 26: case 27: case 28: case 29: case 30:
495 case 31: case 33: case 34: case 35: case 36: case 37:
496 case 38: case 39: case 40:
497 default:
498 break trailLoop;
499 }
500 }
501 count = i + 1;
502
503 // Return the text of the doc comment.
504 return new String(buffer, 0, count);
505 } else {
506 return "";
507 }
508 }
509
510 /**
511 * Scan a number. The first digit of the number should be the current
512 * character. We may be scanning hex, decimal, or octal at this point
513 */
514 private void scanNumber() throws IOException {
515 boolean seenNonOctal = false;
516 boolean overflow = false;
517 boolean seenDigit = false; // used to detect invalid hex number 0xL
518 radix = (ch == '0' ? 8 : 10);
519 long value = ch - '0';
520 count = 0;
521 putc(ch); // save character in buffer
522 numberLoop:
523 for (;;) {
524 switch (ch = in.read()) {
525 case '.':
526 if (radix == 16)
527 break numberLoop; // an illegal character
528 scanReal();
529 return;
530
531 case '8': case '9':
532 // We can't yet throw an error if reading an octal. We might
533 // discover we're really reading a real.
534 seenNonOctal = true;
535 case '0': case '1': case '2': case '3':
536 case '4': case '5': case '6': case '7':
537 seenDigit = true;
538 putc(ch);
539 if (radix == 10) {
540 overflow = overflow || (value * 10)/10 != value;
541 value = (value * 10) + (ch - '0');
542 overflow = overflow || (value - 1 < -1);
543 } else if (radix == 8) {
544 overflow = overflow || (value >>> 61) != 0;
545 value = (value << 3) + (ch - '0');
546 } else {
547 overflow = overflow || (value >>> 60) != 0;
548 value = (value << 4) + (ch - '0');
549 }
550 break;
551
552 case 'd': case 'D': case 'e': case 'E': case 'f': case 'F':
553 if (radix != 16) {
554 scanReal();
651 case 10:
652 env.error(pos, "overflow.long.dec");
653 break;
654 case 16:
655 env.error(pos, "overflow.long.hex");
656 break;
657 default:
658 throw new CompilerError("invalid radix");
659 }
660 }
661 }
662 }
663 }
664
665 /**
666 * Scan a float. We are either looking at the decimal, or we have already
667 * seen it and put it into the buffer. We haven't seen an exponent.
668 * Scan a float. Should be called with the current character is either
669 * the 'e', 'E' or '.'
670 */
671 private void scanReal() throws IOException {
672 boolean seenExponent = false;
673 boolean isSingleFloat = false;
674 char lastChar;
675 if (ch == '.') {
676 putc(ch);
677 ch = in.read();
678 }
679
680 numberLoop:
681 for ( ; ; ch = in.read()) {
682 switch (ch) {
683 case '0': case '1': case '2': case '3': case '4':
684 case '5': case '6': case '7': case '8': case '9':
685 putc(ch);
686 break;
687
688 case 'e': case 'E':
689 if (seenExponent)
690 break numberLoop; // we'll get a format error
967 public long getEndPos() {
968 return in.pos;
969 }
970
971 /**
972 * If the current token is IDENT, return the identifier occurrence.
973 * It will be freshly allocated.
974 */
975 public IdentifierToken getIdToken() {
976 return (token != IDENT) ? null : new IdentifierToken(pos, idValue);
977 }
978
979 /**
980 * Scan the next token.
981 * @return the position of the previous token.
982 */
983 public long scan() throws IOException {
984 return xscan();
985 }
986
987 protected long xscan() throws IOException {
988 final ScannerInputReader in = this.in;
989 long retPos = pos;
990 prevPos = in.pos;
991 docComment = null;
992 while (true) {
993 pos = in.pos;
994
995 switch (ch) {
996 case EOF:
997 token = EOF;
998 return retPos;
999
1000 case '\n':
1001 if (scanComments) {
1002 ch = ' ';
1003 // Avoid this path the next time around.
1004 // Do not just call in.read; we want to present
1005 // a null token (and also avoid read-ahead).
1006 token = COMMENT;
1007 return retPos;
1008 }
1009 case ' ':
1010 case '\t':
1011 case '\f':
1012 ch = in.read();
1013 break;
1014
1015 case '/':
1016 switch (ch = in.read()) {
1017 case '/':
1018 // Parse a // comment
1019 while (((ch = in.read()) != EOF) && (ch != '\n'));
1020 if (scanComments) {
1021 token = COMMENT;
1022 return retPos;
1023 }
1024 break;
1025
1026 case '*':
1027 ch = in.read();
1028 if (ch == '*') {
|
494 case 25: case 26: case 27: case 28: case 29: case 30:
495 case 31: case 33: case 34: case 35: case 36: case 37:
496 case 38: case 39: case 40:
497 default:
498 break trailLoop;
499 }
500 }
501 count = i + 1;
502
503 // Return the text of the doc comment.
504 return new String(buffer, 0, count);
505 } else {
506 return "";
507 }
508 }
509
510 /**
511 * Scan a number. The first digit of the number should be the current
512 * character. We may be scanning hex, decimal, or octal at this point
513 */
514 @SuppressWarnings("fallthrough")
515 private void scanNumber() throws IOException {
516 boolean seenNonOctal = false;
517 boolean overflow = false;
518 boolean seenDigit = false; // used to detect invalid hex number 0xL
519 radix = (ch == '0' ? 8 : 10);
520 long value = ch - '0';
521 count = 0;
522 putc(ch); // save character in buffer
523 numberLoop:
524 for (;;) {
525 switch (ch = in.read()) {
526 case '.':
527 if (radix == 16)
528 break numberLoop; // an illegal character
529 scanReal();
530 return;
531
532 case '8': case '9':
533 // We can't yet throw an error if reading an octal. We might
534 // discover we're really reading a real.
535 seenNonOctal = true;
536 // Fall through
537 case '0': case '1': case '2': case '3':
538 case '4': case '5': case '6': case '7':
539 seenDigit = true;
540 putc(ch);
541 if (radix == 10) {
542 overflow = overflow || (value * 10)/10 != value;
543 value = (value * 10) + (ch - '0');
544 overflow = overflow || (value - 1 < -1);
545 } else if (radix == 8) {
546 overflow = overflow || (value >>> 61) != 0;
547 value = (value << 3) + (ch - '0');
548 } else {
549 overflow = overflow || (value >>> 60) != 0;
550 value = (value << 4) + (ch - '0');
551 }
552 break;
553
554 case 'd': case 'D': case 'e': case 'E': case 'f': case 'F':
555 if (radix != 16) {
556 scanReal();
653 case 10:
654 env.error(pos, "overflow.long.dec");
655 break;
656 case 16:
657 env.error(pos, "overflow.long.hex");
658 break;
659 default:
660 throw new CompilerError("invalid radix");
661 }
662 }
663 }
664 }
665 }
666
667 /**
668 * Scan a float. We are either looking at the decimal, or we have already
669 * seen it and put it into the buffer. We haven't seen an exponent.
670 * Scan a float. Should be called with the current character is either
671 * the 'e', 'E' or '.'
672 */
673 @SuppressWarnings("fallthrough")
674 private void scanReal() throws IOException {
675 boolean seenExponent = false;
676 boolean isSingleFloat = false;
677 char lastChar;
678 if (ch == '.') {
679 putc(ch);
680 ch = in.read();
681 }
682
683 numberLoop:
684 for ( ; ; ch = in.read()) {
685 switch (ch) {
686 case '0': case '1': case '2': case '3': case '4':
687 case '5': case '6': case '7': case '8': case '9':
688 putc(ch);
689 break;
690
691 case 'e': case 'E':
692 if (seenExponent)
693 break numberLoop; // we'll get a format error
970 public long getEndPos() {
971 return in.pos;
972 }
973
974 /**
975 * If the current token is IDENT, return the identifier occurrence.
976 * It will be freshly allocated.
977 */
978 public IdentifierToken getIdToken() {
979 return (token != IDENT) ? null : new IdentifierToken(pos, idValue);
980 }
981
982 /**
983 * Scan the next token.
984 * @return the position of the previous token.
985 */
986 public long scan() throws IOException {
987 return xscan();
988 }
989
990 @SuppressWarnings("fallthrough")
991 protected long xscan() throws IOException {
992 final ScannerInputReader in = this.in;
993 long retPos = pos;
994 prevPos = in.pos;
995 docComment = null;
996 while (true) {
997 pos = in.pos;
998
999 switch (ch) {
1000 case EOF:
1001 token = EOF;
1002 return retPos;
1003
1004 case '\n':
1005 if (scanComments) {
1006 ch = ' ';
1007 // Avoid this path the next time around.
1008 // Do not just call in.read; we want to present
1009 // a null token (and also avoid read-ahead).
1010 token = COMMENT;
1011 return retPos;
1012 }
1013 // Fall through
1014 case ' ':
1015 case '\t':
1016 case '\f':
1017 ch = in.read();
1018 break;
1019
1020 case '/':
1021 switch (ch = in.read()) {
1022 case '/':
1023 // Parse a // comment
1024 while (((ch = in.read()) != EOF) && (ch != '\n'));
1025 if (scanComments) {
1026 token = COMMENT;
1027 return retPos;
1028 }
1029 break;
1030
1031 case '*':
1032 ch = in.read();
1033 if (ch == '*') {
|