📄 javascripttokenmaker.java
字号:
/*
* 10/08/2004
*
* JavaScriptTokenMaker.java - An object that can take a chunk of text and
* return a linked list of <code>Token</code>s
* representing it in the JavaScript programming
* language.
* Copyright (C) 2004 Robert Futrell
* email@address.com
* www.website.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.fife.ui.rsyntaxtextarea.modes;
import javax.swing.text.Segment;
import org.fife.ui.rsyntaxtextarea.*;
/**
* A token maker that turns text into a linked list of <code>Token</code>s
* for syntax highlighting in the JavaScript programming language.
*
* @author Robert Futrell
* @version 0.1
*/
public class JavaScriptTokenMaker extends AbstractTokenMaker {
protected final String operators = "+-*/%!=<>^&|?:";
protected final String separators = "()[]{}";
protected final String separators2 = ".,;"; // Characters you don't want syntax highlighted but separate identifiers.
protected final String hexCharacters = "0123456789ABCDEFabcdef";
protected final String numberEndChars = "FfLl"; // Characters used to specify literal number types.
private int currentTokenStart;
private int currentTokenType;
/*****************************************************************************/
/**
* Constructor.
*/
public JavaScriptTokenMaker() {
super(); // Initializes tokensToHighlight.
}
/*****************************************************************************/
/**
* Checks the token to give it the exact ID it deserves before
* being passed up to the super method.
*
* @param segment <code>Segment</code> to get text from.
* @param start Start offset in <code>segment</code> of token.
* @param end End offset in <code>segment</code> of token.
* @param tokenType The token's type.
* @param startOffset The offset in the document at which the token occurs.
*/
public void addToken(Segment segment, int start, int end, int tokenType, int startOffset) {
switch (tokenType) {
// Since reserved words, functions, and data types are all passed
// into here as "identifiers," we have to see what the token
// really is...
case Token.IDENTIFIER:
int value = wordsToHighlight.get(segment, start,end);
if (value!=-1)
tokenType = value;
break;
case Token.WHITESPACE:
case Token.SEPARATOR:
case Token.OPERATOR:
case Token.ERROR_IDENTIFIER:
case Token.ERROR_NUMBER_FORMAT:
case Token.ERROR_STRING_DOUBLE:
case Token.ERROR_CHAR:
case Token.COMMENT_EOL:
case Token.COMMENT_MULTILINE:
case Token.LITERAL_BOOLEAN:
case Token.LITERAL_NUMBER_DECIMAL_INT:
case Token.LITERAL_NUMBER_FLOAT:
case Token.LITERAL_NUMBER_HEXADECIMAL:
case Token.LITERAL_STRING_DOUBLE_QUOTE:
case Token.LITERAL_CHAR:
break;
default:
System.err.println("Unknown tokenType in JavaScriptTokenMaker.addToken: '" + tokenType + "'");
System.exit(0);
}
super.addToken(segment, start, end, tokenType, startOffset);
}
/*****************************************************************************/
/**
* Returns the words to highlightfor the JavaScript programming language.
*
* @return A <code>TokenMap</code> containing the words to highlight for
* the JavaScript programming language.
* @see org.fife.ui.rsyntaxtextarea.AbstractTokenMaker#getWordsToHighlight
*/
public TokenMap getWordsToHighlight() {
TokenMap tokenMap = new TokenMap(52);
int reservedWord = Token.RESERVED_WORD;
tokenMap.put("abstract", reservedWord);
tokenMap.put("as", reservedWord);
tokenMap.put("break", reservedWord);
tokenMap.put("case", reservedWord);
tokenMap.put("catch", reservedWord);
tokenMap.put("class", reservedWord);
tokenMap.put("const", reservedWord);
tokenMap.put("continue", reservedWord);
tokenMap.put("debugger", reservedWord);
tokenMap.put("default", reservedWord);
tokenMap.put("delete", reservedWord);
tokenMap.put("do", reservedWord);
tokenMap.put("else", reservedWord);
tokenMap.put("enum", reservedWord);
tokenMap.put("export", reservedWord);
tokenMap.put("extends", reservedWord);
tokenMap.put("final", reservedWord);
tokenMap.put("finally", reservedWord);
tokenMap.put("for", reservedWord);
tokenMap.put("function", reservedWord);
tokenMap.put("goto", reservedWord);
tokenMap.put("if", reservedWord);
tokenMap.put("implements", reservedWord);
tokenMap.put("import", reservedWord);
tokenMap.put("in", reservedWord);
tokenMap.put("instanceof", reservedWord);
tokenMap.put("interface", reservedWord);
tokenMap.put("item", reservedWord);
tokenMap.put("namespace", reservedWord);
tokenMap.put("native", reservedWord);
tokenMap.put("new", reservedWord);
tokenMap.put("null", reservedWord);
tokenMap.put("package", reservedWord);
tokenMap.put("private", reservedWord);
tokenMap.put("protected", reservedWord);
tokenMap.put("public", reservedWord);
tokenMap.put("return", reservedWord);
tokenMap.put("static", reservedWord);
tokenMap.put("super", reservedWord);
tokenMap.put("switch", reservedWord);
tokenMap.put("synchronized", reservedWord);
tokenMap.put("this", reservedWord);
tokenMap.put("throw", reservedWord);
tokenMap.put("throws", reservedWord);
tokenMap.put("transient", reservedWord);
tokenMap.put("try", reservedWord);
tokenMap.put("typeof", reservedWord);
tokenMap.put("var", reservedWord);
tokenMap.put("void", reservedWord);
tokenMap.put("while", reservedWord);
tokenMap.put("with", reservedWord);
int literalBoolean = Token.LITERAL_BOOLEAN;
tokenMap.put("false", literalBoolean);
tokenMap.put("true", literalBoolean);
int dataType = Token.DATA_TYPE;
tokenMap.put("boolean", dataType);
tokenMap.put("byte", dataType);
tokenMap.put("char", dataType);
tokenMap.put("double", dataType);
tokenMap.put("float", dataType);
tokenMap.put("int", dataType);
tokenMap.put("long", dataType);
tokenMap.put("short", dataType);
return tokenMap;
}
/*****************************************************************************/
/**
* Returns the first token in the linked list of tokens generated
* from <code>text</code>. This method must be implemented by
* subclasses so they can correctly implement syntax highlighting.
*
* @param text The text from which to get tokens.
* @param initialTokenType The token type we should start with.
* @param startOffset The offset into the document at which
* <code>text</code> starts.
* @return The first <code>Token</code> in a linked list representing
* the syntax highlighted text.
*/
public Token getTokenList(Segment text, int initialTokenType,
int startOffset) {
resetTokenList();
char[] array = text.array;
int offset = text.offset;
int count = text.count;
int end = offset + count;
// See, when we find a token, its starting position is always of the
// form: 'startOffset + (currentTokenStart-offset)'; but since
// startOffset and offset are constant, tokens' starting positions
// become: 'newStartOffset+currentTokenStart' for one less subraction
// operation.
int newStartOffset = startOffset - offset;
currentTokenStart = offset;
currentTokenType = initialTokenType;
boolean backslash = false;
boolean numContainsExponent = false;
boolean numContainsEndCharacter = false;
for (int i=offset; i<end; i++) {
char c = array[i];
switch (currentTokenType) {
case Token.NULL:
currentTokenStart = i; // Starting a new token here.
switch (c) {
case ' ':
case '\t':
currentTokenType = Token.WHITESPACE;
break;
case '"':
if (backslash) { // Escaped double quote => call '"' an identifier..
addToken(text, currentTokenStart,i, Token.IDENTIFIER, newStartOffset+currentTokenStart);
backslash = false;
}
else {
currentTokenType = Token.ERROR_STRING_DOUBLE;
}
break;
case '\'':
if (backslash) { // Escaped single quote => call '\'' an identifier.
addToken(text, currentTokenStart,i, Token.IDENTIFIER, newStartOffset+currentTokenStart);
backslash = false;
}
else {
currentTokenType = Token.ERROR_CHAR;
}
break;
case '\\':
addToken(text, currentTokenStart,i, Token.IDENTIFIER, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
backslash = !backslash;
break;
default:
if (RSyntaxUtilities.isDigit(c)) {
currentTokenType = Token.LITERAL_NUMBER_DECIMAL_INT;
break;
}
else if (RSyntaxUtilities.isLetter(c) || c=='_') {
currentTokenType = Token.IDENTIFIER;
break;
}
int indexOf = operators.indexOf(c,0);
if (indexOf>-1) {
currentTokenStart = i;
currentTokenType = Token.OPERATOR;
break;
}
indexOf = separators.indexOf(c,0);
if (indexOf>-1) {
addToken(text, currentTokenStart,i, Token.SEPARATOR, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
break;
}
indexOf = separators2.indexOf(c,0);
if (indexOf>-1) {
addToken(text, currentTokenStart,i, Token.IDENTIFIER, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
break;
}
else {
currentTokenType = Token.ERROR_IDENTIFIER;
break;
}
} // End of switch (c).
break;
case Token.WHITESPACE:
switch (c) {
case ' ':
case '\t':
break; // Still whitespace.
case '\\':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -