📄 scanner.java
字号:
} else if (!firstLine) {
for (int i = 1; i < col; i++) {
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = ' ';
}
}
linestart = true;
textLoop:
while (bp < buflen) {
switch (ch) {
case '*':
linestart = false;
scanDocCommentChar();
if (ch == '/') {
break outerLoop;
}
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = '*';
break;
case ' ':
case '\t':
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = (char) ch;
scanDocCommentChar();
break;
case FF:
scanDocCommentChar();
break textLoop;
case CR:
scanDocCommentChar();
if (ch != LF) {
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = (char) LF;
break;
}
case LF:
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = (char) ch;
scanDocCommentChar();
break textLoop;
default:
if (ch == '@' && linestart) {
int start = bp + 1;
do {
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = (char) ch;
scanDocCommentChar();
} while ('a' <= ch && ch <= 'z')
;
if (names.fromChars(buf, start, bp - start) ==
names.deprecated) {
deprecatedFlag = true;
}
} else {
if (count == buffer.length)
expandCommentBuffer();
buffer[count++] = (char) ch;
scanDocCommentChar();
}
linestart = false;
}
}
firstLine = false;
}
if (count > 0) {
int i = count - 1;
trailLoop:
while (i > -1) {
switch (buffer[i]) {
case '*':
i--;
break;
default:
break trailLoop;
}
}
count = i + 1;
return new String(buffer, 0, count);
} else {
return "";
}
}
/**
* The value of a literal token, recorded as a string.
* For integers, leading 0x and 'l' suffixes are suppressed.
*/
public String stringVal() {
return new String(sbuf, 0, sp);
}
/**
*在nextToken方法中集中实现了扫描下一个符号的功能,根据当前字符判断下一个字符的用途,然后调用相应的处理函数来处理。
*在这里实现的扫描功能有:
*1。空白字符的过滤,在遇到空白字符的时候,调用scanChar方法读取下一个字符,
*不做任何处理。
*2,当前字符是26个字母中的一个或者是"$和"_"的话,处理方法是调用scanIdent方法
*对其余部分扫描。
*3,如果当前字符是0,后面一个是x的话说明这是一个16进制数,如果是其
*他数字,则是个8进制数字,如果当前字符为非0数字的话,那就是一
*个10进制数字,这将调用scannumber方法来处理。
*4,如果是小数点的话,要分开处理,后面是数字的话,则作为小数点处理,
*否则就是一个“DOT”。
*5。对于单独的字符,他们可以直接对应相应的单词符号,如:{ -〉LBRACE。
*6,过滤源代码的注释也可以实现。如果遇到字符/,如果后面是一个/,
*则表明它是一个到行尾的注释,调用scanCommentChar()方法;
*如果后面是*,则说明是一个多行注释,并且进一步查看下一个字符是否为*,
*是的话则是可以用javadoc工具提取的文档文件,调用scanDocComment()
*,否则skipComment()跳过注释。在遇到字符‘,“时,说明是
*字符或字符串符号。
*/
public void nextToken() {
try {
prevEndPos = endPos;
sp = 0;
docComment = null;
while (true) {
pos = (line << Position.LINESHIFT) + col;
int start = bp;
switch (ch) {
case ' ':
case '\t':
case FF:
case CR:
case LF:
scanChar();
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case '$':
case '_':
scanIdent();
return;
case '0':
scanChar();
if (ch == 'x' || ch == 'X') {
scanChar();
if (digit(16) < 0) {
lexError("invalid.hex.number");
}
scanNumber(16);
} else {
putChar('0');
scanNumber(8);
}
return;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
scanNumber(10);
return;
case '.':
scanChar();
if ('0' <= ch && ch <= '9') {
putChar('.');
scanFractionAndSuffix();
} else {
token = DOT;
}
return;
case ',':
scanChar();
token = COMMA;
return;
case ';':
scanChar();
token = SEMI;
return;
case '(':
scanChar();
token = LPAREN;
return;
case ')':
scanChar();
token = RPAREN;
return;
case '[':
scanChar();
token = LBRACKET;
return;
case ']':
scanChar();
token = RBRACKET;
return;
case '{':
scanChar();
token = LBRACE;
return;
case '}':
scanChar();
token = RBRACE;
return;
case '/':
scanChar();
if (ch == '/') {
do {
scanCommentChar();
} while (ch != CR && ch != LF && bp < buflen)
;
break;
} else if (ch == '*') {
scanChar();
if (ch == '*') {
docComment = scanDocComment();
} else {
skipComment();
}
if (ch == '/') {
scanChar();
break;
} else {
lexError("unclosed.comment");
return;
}
} else if (ch == '=') {
name = names.slashequals;
token = SLASHEQ;
scanChar();
} else {
name = names.slash;
token = SLASH;
}
return;
case '\'':
scanChar();
if (ch == '\'') {
lexError("empty.char.lit");
} else {
if (ch == CR || ch == LF)
lexError(pos, "illegal.line.end.in.char.lit");
scanLitChar();
if (ch == '\'') {
scanChar();
token = CHARLITERAL;
} else {
lexError(pos, "unclosed.char.lit");
}
}
return;
case '\"':
scanChar();
while (ch != '\"' && ch != CR && ch != LF && bp < buflen)
scanLitChar();
if (ch == '\"') {
token = STRINGLITERAL;
scanChar();
} else {
lexError(pos, "unclosed.str.lit");
}
return;
default:
if (isSpecial(ch)) {
scanOperator();
} else if (Character.isJavaIdentifierStart(ch)) {
scanIdent();
} else if (bp == buflen || ch == EOI && bp + 1 == buflen) {
token = EOF;
} else {
lexError("illegal.char", String.valueOf((int) ch));
scanChar();
}
return;
}
}
}
finally { endPos = (line << Position.LINESHIFT) + col - 1;
} }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -