📄 javascanner.java
字号:
package se.sics.mspsim.extutil.highlight;// Public domain, no restrictions, Ian Holyer, University of Bristol./** * <p> * Provide a hand-written scanner for the Java language. */public class JavaScanner extends Scanner { // The version of Java supported. private int version = 15; private boolean debug = false; /** Create a Java scanner, for Java version 1.5 by default. */ public JavaScanner() { super(); initKind(); initUniKind(); } /** Create a Java scanner, for a given version between "1.1" and "1.5". */ public JavaScanner(String version) { super(); initKind(); initUniKind(); if (version.equals("1.1")) this.version = 11; else if (version.equals("1.2")) this.version = 12; else if (version.equals("1.3")) this.version = 13; else if (version.equals("1.4")) this.version = 14; else if (version.equals("1.5")) this.version = 15; else throw new Error("Unknown version of Java: " + version); } /** Override the read method from the Scanner class. */ protected int read() { int type, saveStart = 0; if (debug) saveStart = start; if (start >= end) return WHITESPACE; switch (state) { case MID_COMMENT: case END_COMMENT: type = readComment(MID_COMMENT); if (type == END_COMMENT) state = WHITESPACE; else state = MID_COMMENT; return type; default: char c = buffer[start]; if (c == '\\') c = next(); if (c < 128) type = kind[c]; else type = unikind[Character.getType(c)]; switch (type) { case WHITESPACE: start = start + charlength; charlength = 1; while (start < end) { c = buffer[start]; if (c == '\\') c = next(); int k; if (c < 128) k = kind[c]; else k = unikind[Character.getType(c)]; if (k != WHITESPACE) break; start = start + charlength; charlength = 1; } break; case UNRECOGNIZED: case BRACKET: case SEPARATOR: start = start + charlength; charlength = 1; break; case OPERATOR: start = start + charlength; charlength = 1; type = readOperator(c); break; case CHARACTER: start = start + charlength; charlength = 1; type = readCharLiteral(); break; case STRING: start = start + charlength; charlength = 1; type = readStringLiteral(); break; case IDENTIFIER: start = start + charlength; charlength = 1; while (start < end) { c = buffer[start]; if (c == '\\') c = next(); int k; if (c < 128) k = kind[c]; else k = unikind[Character.getType(c)]; if (k != IDENTIFIER && k != NUMBER) break; start = start + charlength; charlength = 1; } break; case NUMBER: start = start + charlength; charlength = 1; type = readNumber(c); break; case PUNCTUATION: start = start + charlength; charlength = 1; type = readDot(); break; case COMMENT: start = start + charlength; charlength = 1; type = readSlash(); if (type == START_COMMENT) state = MID_COMMENT; break; } } if (debug) { System.out.print(TokenTypes.typeNames[type]); System.out.println(" " + saveStart + "," + end + "(" + (start - saveStart) + ")"); } return type; } private int readOperator(char c) { if (start >= end) return OPERATOR; char c2; switch (c) { case '~': case '?': case ':': break; case '+': case '-': case '&': case '|': c2 = buffer[start]; if (c2 == '\\') c2 = next(); if (c2 != c && c2 != '=') break; start = start + charlength; charlength = 1; break; case '=': case '*': case '!': case '^': case '%': case '/': c2 = buffer[start]; if (c2 == '\\') c2 = next(); if (c2 != '=') break; start = start + charlength; charlength = 1; break; case '<': case '>': c2 = buffer[start]; if (c2 == '\\') c2 = next(); if (c2 == '=') { start = start + charlength; charlength = 1; } else if (c2 == c) { start = start + charlength; charlength = 1; if (start >= end) break; char c3 = buffer[start]; if (c3 == '\\') c3 = next(); if (c3 == '=') { start = start + charlength; charlength = 1; } else if (c == '>' && c3 == '>') // >>> { start = start + charlength; charlength = 1; if (start >= end) break; char c4 = buffer[start]; if (c4 == '\\') c4 = next(); if (c4 != '=') break; start = start + charlength; charlength = 1; } } break; } return OPERATOR; } private int readCharLiteral() { if (start >= end) return bad(CHARACTER); char c2 = buffer[start]; if (c2 == '\\') c2 = next(); switch (c2) { case '\\': start = start + charlength; charlength = 1; boolean ok = readEscapeSequence(); if (!ok) return bad(CHARACTER); break; case '\'': case '\n': return bad(CHARACTER); default: start = start + charlength; charlength = 1; break; } if (start >= end) return bad(CHARACTER); char c3 = buffer[start]; if (c3 == '\\') c3 = next(); if (c3 != '\'') return bad(CHARACTER); start = start + charlength; charlength = 1; return CHARACTER; } private int readStringLiteral() { if (start >= end) return bad(STRING); char c = buffer[start]; if (c == '\\') c = next(); while (c != '"') { switch (c) { case '\\': start = start + charlength; charlength = 1; boolean ok = readEscapeSequence(); if (!ok) return bad(STRING); break; case '\n': return bad(STRING); default: start = start + charlength; charlength = 1; if (start >= end) return bad(STRING); break; } c = buffer[start]; if (c == '\\') c = next(); } if (c != '"') return bad(STRING); start = start + charlength; charlength = 1; return STRING; } private int readSlash() { if (start >= end) return OPERATOR; char c = buffer[start]; if (c == '\\') c = next(); if (c == '/') { while (c != '\n') { start = start + charlength; charlength = 1; if (start >= end) return COMMENT; c = buffer[start]; if (c == '\\') c = next(); } start = start + charlength; charlength = 1; return COMMENT; } else if (c == '*') { start = start + charlength; charlength = 1; return readComment(START_COMMENT); } return readOperator('/'); } // Read one line of a /*...*/ comment, given the expected type int readComment(int type) { if (start >= end) return type; char c = buffer[start]; if (c == '\\') c = next(); while (true) { while (c != '*' && c != '\n') { start = start + charlength; charlength = 1; if (start >= end) return type; c = buffer[start]; if (c == '\\') c = next(); } start = start + charlength; charlength = 1; if (c == '\n') return type; if (start >= end) return type; c = buffer[start]; if (c == '\\') c = next(); if (c == '/') { start = start + charlength; charlength = 1; if (type == START_COMMENT) { return COMMENT; } return END_COMMENT; } } } // Read a number, without checking whether it is out of range // Doesn't deal with e.g. 0777.9 or 07779f private int readNumber(char c) { if (c == '0') { int saveStart = start, saveLength = charlength; start = start + charlength; charlength = 1; if (start >= end) return NUMBER; char c2 = buffer[start]; if (c2 == '\\') c2 = next(); switch (c2) { case 'x': case 'X': start = start + charlength; charlength = 1; boolean ok = readDigits(16); if (!ok) return bad(NUMBER); readSuffix(); return NUMBER; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: readDigits(8); readSuffix(); return NUMBER; case '.': case 'e': case 'E': start = saveStart; charlength = saveLength; break; case 'f': case 'F': case 'd': case 'D': start = start + charlength; charlength = 1; return NUMBER; case 'l': case 'L': start = start + charlength; charlength = 1; return NUMBER; } } boolean hasDigits = false; if ('0' <= c && c <= '9') { hasDigits = true; readDigits(10); if (start >= end) return NUMBER; c = buffer[start]; if (c == '\\') c = next(); if (c == 'l' || c == 'L') { start = start + charlength; charlength = 1; return NUMBER; } } if (c == '.') { start = start + charlength; charlength = 1; if (start >= end) return NUMBER; c = buffer[start]; if (c == '\\') c = next(); if ('0' <= c && c <= '9') { hasDigits = true; readDigits(10); if (start >= end) return NUMBER; c = buffer[start]; if (c == '\\') c = next(); } } if (!hasDigits) return bad(NUMBER); switch (c) { case 'e': case 'E': start = start + charlength; charlength = 1; if (start >= end) return bad(NUMBER); c = buffer[start]; if (c == '\\') c = next(); if (c == '+' || c == '-') { start = start + charlength; charlength = 1; if (start >= end) return bad(NUMBER); c = buffer[start]; if (c == '\\') c = next(); } readDigits(10); break; case 'f': case 'F': case 'd': case 'D': start = start + charlength; charlength = 1; return NUMBER; } return NUMBER; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -