📄 scanner.java
字号:
case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '$': case '_': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break; default: if (!Character.isJavaIdentifierPart(ch) || bp >= buflen) { name = names.fromChars(sbuf, 0, sp); token = keywords.key(name); return; } } } while (true) ; } /** * Return true if ch can be part of an operator. */ private boolean isSpecial(char ch) { switch (ch) { case '!': case '%': case '&': case '*': case '?': case '+': case '-': case ':': case '<': case '=': case '>': case '^': case '|': case '~': return true; default: return false; } } /** * Read longest possible sequence of special characters and convert * to token. */ private void scanOperator() { while (true) { putChar(ch); Name newname = names.fromChars(sbuf, 0, sp); if (keywords.key(newname) == IDENTIFIER) { sp--; break; } name = newname; token = keywords.key(newname); scanChar(); if (!isSpecial(ch)) break; } } /** * Scan a doccomment line after the inital '*''s for * a @deprecated tag. This should be extended to support all javadoc tags. */ private void scanDocCommentTag() { int start = bp + 1; do { scanDocCommentChar(); } while ('a' <= ch && ch <= 'z') ; if (names.fromChars(buf, start, bp - start) == names.deprecated) { deprecatedFlag = true; } } /** * Skip a non-documentation comment. This method should be called once * the initial /, * and the next character have been read. */ private void skipComment() { while (bp < buflen) { switch (ch) { case '*': scanChar(); if (ch == '/') return; break; default: scanCommentChar(); break; } } } /** * * Scan a documention comment and return it as a string. This method * should be called once the initial /, * and * have been read. It * gathers the content of the comment (witout leading spaces and '*'s) * in the string buffer. Stops on the close '/'. */ private String scanDocComment() { if (buffer == null) buffer = new char[1024]; count = 0; boolean linestart = false; boolean firstLine = true; while (bp < buflen && ch == '*') { scanDocCommentChar(); } if (bp < buflen && ch == '/') { return ""; } if (bp < buflen) { if (ch == LF) { scanDocCommentChar(); firstLine = false; } else if (ch == CR) { scanDocCommentChar(); if (ch == LF) { scanDocCommentChar(); firstLine = false; } } } outerLoop: while (bp < buflen) { wsLoop: while (bp < buflen) { switch (ch) { case ' ': scanDocCommentChar(); break; case '\t': col = ((col - 1) / TabInc * TabInc) + TabInc; scanDocCommentChar(); break; case FF: col = 0; scanDocCommentChar(); break; default: break wsLoop; } } if (ch == '*') { do { scanDocCommentChar(); } while (ch == '*') ; if (ch == '/') { break outerLoop; } } 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); } /** * Read token. */ 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 + -