📄 unixshelltokenmaker.java
字号:
if (RSyntaxUtilities.isDigit(c)) {
break; // Still a literal number.
}
int indexOf = operators.indexOf(c);
if (indexOf>-1) {
addToken(text, currentTokenStart,i-1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset+currentTokenStart);
addToken(text, i,i, Token.OPERATOR, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
indexOf = separators.indexOf(c);
if (indexOf>-1) {
addToken(text, currentTokenStart,i-1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset+currentTokenStart);
addToken(text, i,i, Token.SEPARATOR, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
indexOf = separators2.indexOf(c);
if (indexOf>-1) {
addToken(text, currentTokenStart,i-1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset+currentTokenStart);
addToken(text, i,i, Token.IDENTIFIER, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
// Otherwise, remember this was a number and start over.
addToken(text, currentTokenStart,i-1, Token.LITERAL_NUMBER_DECIMAL_INT, newStartOffset+currentTokenStart);
i--;
currentTokenType = Token.NULL;
} // End of switch (c).
break;
case Token.VARIABLE:
// Note that we first arrive here AFTER the '$' character.
// First check if the variable name is enclosed in '{' and '}' characters.
if (c=='{') {
while (++i<end) {
if (array[i]=='}') {
addToken(text, currentTokenStart,i, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
break;
}
} // End of while (++i<end).
if (i==end) { // Happens when '}' wasn't found...
addToken(text, currentTokenStart,end-1, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
}
break;
} // End of if (i<end-1 && array[i+1]=='{').
// If we didn't find the '{' character, find the end of the variable...
while (i<end) {
c = array[i]; // Not needed the first iteration, but can't think of a better way to do it...
if (!RSyntaxUtilities.isLetterOrDigit(c) && shellVariables.indexOf(c)==-1 && c!='_') {
addToken(text, currentTokenStart,i-1, Token.VARIABLE, newStartOffset+currentTokenStart);
i--;
currentTokenType = Token.NULL;
break;
}
i++;
}
// This only happens if we never found the end of the variable in the loop above.
if (i==end) {
addToken(text, currentTokenStart,i-1, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
}
break;
case Token.COMMENT_EOL:
// If we got here, then the line != "#" only, so check for "#!".
if (c=='!')
currentTokenType = Token.PREPROCESSOR;
i = end - 1;
addToken(text, currentTokenStart,i, currentTokenType, newStartOffset+currentTokenStart);
// We need to set token type to null so at the bottom we don't add one more token.
currentTokenType = Token.NULL;
break;
case Token.LITERAL_CHAR:
if (c=='\\') {
backslash = !backslash; // Okay because if we got in here, backslash was initially false.
}
else {
if (c=='\'' && !backslash) {
addToken(text, currentTokenStart,i, Token.LITERAL_CHAR, newStartOffset+currentTokenStart);
currentTokenStart = i + 1;
currentTokenType = Token.NULL;
// backslash is definitely false when we leave.
}
backslash = false; // Need to set backslash to false here as a character was typed.
}
// Otherwise, we're still an unclosed char literal...
break;
case Token.LITERAL_BACKQUOTE:
switch (c) {
case '\\':
backslash = !backslash;
break;
case '`':
if (!backslash) {
addToken(text, currentTokenStart,i, Token.LITERAL_BACKQUOTE, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
// backslash is definitely false when we leave.
break;
}
backslash = false;
break;
// Variable in the backquote string...
case '$':
if (backslash==true) {
backslash = false;
break;
}
// Add the string up-to the variable.
addToken(text, currentTokenStart,i-1, Token.LITERAL_BACKQUOTE, newStartOffset+currentTokenStart);
currentTokenType = Token.VARIABLE;
currentTokenStart = i;
// First check if the variable name is enclosed in '{' and '}' characters.
if (i<end-1 && array[i+1]=='{') {
i++; // Now we're on the '{' char.
while (++i<end) {
if (array[i]=='}') {
addToken(text, currentTokenStart,i, Token.VARIABLE, newStartOffset+currentTokenStart);
i++;
if (i<end) {
c = array[i];
if (c=='`') { // The only rub - back quote right after variable.
addToken(text, i,i, Token.LITERAL_BACKQUOTE, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
else { // Continue on with the string.
currentTokenStart = i;
currentTokenType = Token.LITERAL_BACKQUOTE;
i--;
break;
}
}
else { // i==end = "trick" this method so that the string is continued to the next line.
currentTokenStart = i;
currentTokenType = Token.LITERAL_BACKQUOTE;
break; // So we don't hit the condition below.
}
} // End of if (array[i]=='}').
} // End of while (++i<end).
if (i==end) { // Happens when '}' wasn't found...
addToken(text, currentTokenStart,end-1, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenStart = end; // ???
currentTokenType = Token.LITERAL_BACKQUOTE;
break;
}
} // End of if (i<end-1 && array[i+1]=='{').
// If we reached the end of the variable, get out.
if (currentTokenType==Token.NULL || currentTokenType==Token.LITERAL_BACKQUOTE)
break;
// If we didn't find the '{' character, find the end of the variable...
// Increment first to skip the '$'.
while (++i<end) {
c = array[i];
if (!RSyntaxUtilities.isLetterOrDigit(c) && shellVariables.indexOf(c)==-1 && c!='_') {
addToken(text, currentTokenStart,i-1, Token.VARIABLE, newStartOffset+currentTokenStart);
if (c=='`') { // The only rub.
addToken(text, i,i, Token.LITERAL_BACKQUOTE, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
else {
currentTokenStart = i;
currentTokenType = Token.LITERAL_BACKQUOTE;
i--;
break;
}
}
}
// This only happens if we never found the end of the variable in the loop above.
// We "trick" this method so that the backquote string token is at the end.
if (i==end) {
addToken(text, currentTokenStart,i-1, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenStart = i;
currentTokenType = Token.LITERAL_BACKQUOTE;
}
break;
// Otherwise, we're still in an unclosed string...
default:
backslash = false; // Need to set backslash to false here as a character was typed.
} // End of switch (c).
break;
case Token.LITERAL_STRING_DOUBLE_QUOTE:
switch (c) {
case '\\':
backslash = !backslash;
break;
case '"':
if (!backslash) {
addToken(text, currentTokenStart,i, Token.LITERAL_STRING_DOUBLE_QUOTE, newStartOffset+currentTokenStart);
currentTokenType = Token.NULL;
// backslash is definitely false when we leave.
break;
}
backslash = false;
break;
// Variable in the double-quoted string...
case '$':
if (backslash==true) {
backslash = false;
break;
}
// Add the string up-to the variable.
addToken(text, currentTokenStart,i-1, Token.LITERAL_STRING_DOUBLE_QUOTE, newStartOffset+currentTokenStart);
currentTokenType = Token.VARIABLE;
currentTokenStart = i;
// First check if the variable name is enclosed in '{' and '}' characters.
if (i<end-1 && array[i+1]=='{') {
i++; // Now we're on the '{' char.
while (++i<end) {
if (array[i]=='}') {
addToken(text, currentTokenStart,i, Token.VARIABLE, newStartOffset+currentTokenStart);
i++;
if (i<end) {
c = array[i];
if (c=='"') { // The only rub - double-quote right after variable.
addToken(text, i,i, Token.LITERAL_STRING_DOUBLE_QUOTE, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
else { // Continue on with the string.
currentTokenStart = i;
currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
i--;
break;
}
}
else { // i==end = "trick" this method so that the string is continued to the next line.
currentTokenStart = i;
currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
break; // So we don't hit the condition below.
}
} // End of if (array[i]=='}').
} // End of while (++i<end).
if (i==end) { // Happens when '}' wasn't found...
addToken(text, currentTokenStart,end-1, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenStart = end; // ???
currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
break;
}
} // End of if (i<end-1 && array[i+1]=='{').
// If we reached the end of the variable, get out.
if (currentTokenType==Token.NULL || currentTokenType==Token.LITERAL_STRING_DOUBLE_QUOTE)
break;
// If we didn't find the '{' character, find the end of the variable...
// Increment first to skip the '$'.
while (++i<end) {
c = array[i];
if (!RSyntaxUtilities.isLetterOrDigit(c) && shellVariables.indexOf(c)==-1 && c!='_') {
addToken(text, currentTokenStart,i-1, Token.VARIABLE, newStartOffset+currentTokenStart);
if (c=='"') { // The only rub.
addToken(text, i,i, Token.LITERAL_STRING_DOUBLE_QUOTE, newStartOffset+i);
currentTokenType = Token.NULL;
break;
}
else {
currentTokenStart = i;
currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
i--;
break;
}
}
}
// This only happens if we never found the end of the variable in the loop above.
// We "trick" this method so that the double-quote string token is at the end.
if (i==end) {
addToken(text, currentTokenStart,i-1, Token.VARIABLE, newStartOffset+currentTokenStart);
currentTokenStart = i;
currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE;
}
break;
// Otherwise, we're still in an unclosed string...
default:
backslash = false; // Need to set backslash to false here as a character was typed.
} // End of switch (c).
break;
default:
System.err.println("Invalid currentTokenType: " + currentTokenType + "; c=='" + c + "'");
System.exit(0);
} // End of switch (currentTokenType).
} // End of for (int i=offset; i<end; i++).
switch (currentTokenType) {
// Remember what token type to begin the next line with.
case Token.LITERAL_BACKQUOTE:
case Token.LITERAL_STRING_DOUBLE_QUOTE:
case Token.LITERAL_CHAR:
addToken(text, currentTokenStart,end-1, currentTokenType, newStartOffset+currentTokenStart);
break;
// Do nothing if everything was okay.
case Token.NULL:
addNullToken();
break;
// All other token types don't continue to the next line...
default:
addToken(text, currentTokenStart,end-1, currentTokenType, newStartOffset+currentTokenStart);
addNullToken();
}
// Return the first token in our linked list.
return firstToken;
}
/*****************************************************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -