Files
VisualSapfor/src/Common/UI/Themes/FortranSPFTokenMaker.java
2023-09-17 22:13:42 +03:00

409 lines
17 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package Common.UI.Themes;
import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.TokenMap;
import javax.swing.text.Segment;
public class FortranSPFTokenMaker extends ProvidedTokenMaker {
@Override
public TokenMap getWordsToHighlight() {
TokenMap tokenMap = new TokenMap(true);
fillTokenMap(tokenMap, Token.RESERVED_WORD,
"FORALL", "ENDFORALL", "PUBLIC", "PRIVATE", "ADMIT", "ASSIGNMENT", "CALL", "COMMON",
"CYCLE", "DIMENSION", "END", "ENDDO", "ENTRY", "FORMAT", "IMPLICIT", "INTENT", "MAP",
"OPEN", "POINTER", "PROGRAM", "RECURSIVE", "STOP", "THEN", "WHILE", "ALLOCATABLE",
"ATEND", "CASE", "COMPLEX", "DATA", "DO", "ENDFILE", "EQUIVALENCE", "FUNCTION",
"INCLUDE", "INTERFACE", "MODULE", "OPTIONAL", "PRINT", "PURE", "READ", "RETURN",
"STRUCTURE", "TYPE", "WRITE", "ALLOCATE", "BACKSPACE", "CHARACTER", "CONTAINS",
"DEALLOCATE", "DOUBLE", "ENDIF", "EXIT", "GOTO", "INQUIRE", "INTRINSIC", "NAMELIST",
"PARAMETER", "PRECISION", "REAL", "REWIND", "SUBROUTINE", "UNION", "ASSIGN", "BLOCKDATA",
"CLOSE", "CONTINUE", "DEFAULT", "ELSE", "ELSEIF", "ENDSELECT", "EXTERNAL", "IF", "INTEGER",
"LOGICAL", "NONE", "PAUSE", "PROCEDURE", "RECORD", "SAVE", "TARGET", "USE", "SELECT", "BLOCK", "WHERE"
);
fillTokenMap(tokenMap, Token.OPERATOR,
".EQ.",
".NE.", ".LT.", ".LE.",
".GT.", ".GE.",
".NOT.", ".AND.", ".EQV.", ".NEQV.",
".OR.", ".TRUE.", ".FALSE."
);
return tokenMap;
}
@Override
public void addToken(Segment segment, int start, int end, int tokenType, int startOffset) {
int finalTokenType = tokenType;
switch (tokenType) {
case Token.COMMENT_EOL:
if (segment.count >= 5) {
switch (segment.subSequence(1, 5).toString().toUpperCase()) {
case "$SPF":
finalTokenType = Token.COMMENT_DOCUMENTATION;
break;
case "DVM$":
finalTokenType = Token.COMMENT_MARKUP;
break;
case "$OMP":
finalTokenType = Token.COMMENT_KEYWORD;
break;
default:
break;
}
}
break;
case Token.IDENTIFIER:
int value = wordsToHighlight.get(segment, start, end);
//ключевое слово
if (value != -1) {
finalTokenType = value;
}
break;
default:
break;
}
super.addToken(segment, start, end, finalTokenType, startOffset);
}
@Override
public void Body(TokenProvider provider) {
switch (provider.position) {
//<editor-fold desc="Зона переноса">
case 0:
//тут всегда currentTokenType=NULL. переносимый известеи в startTokenType
provider.start();
switch (provider.c) {
case '!':
case '*':
case 'C':
case 'c':
case 'D':
case 'd':
//комментарий. анализ закончен
provider.setType(Token.COMMENT_EOL);
provider.stop();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
//метка.
provider.setType(Token.MARKUP_TAG_NAME);
provider.label_flag = true;
break;
case ' ':
case '\r':
//пробелы
provider.setType(Token.WHITESPACE);
break;
case '\t':
provider.SkipWrap();
break;
default:
//все остальное
provider.setType(Token.IDENTIFIER);
break;
}
break;
case 1:
case 2:
case 3:
case 4:
switch (provider.currentTokenType) {
case Token.MARKUP_TAG_NAME:
switch (provider.c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '\r':
break;
case '!':
SaveCurrent(provider);
provider.start();
//комментарий. анализ закончен
provider.setType(Token.COMMENT_EOL);
provider.stop();
break;
case ' ':
SaveCurrent(provider);
provider.start();
provider.setType(Token.WHITESPACE);
break;
case '\t':
SaveCurrent(provider);
provider.start();
provider.SkipWrap();
break;
default:
//это не метка. меняем тип.
provider.setType(Token.IDENTIFIER);
break;
}
break;
case Token.WHITESPACE:
switch (provider.c) {
case ' ':
case '\r':
break;
case '\t':
provider.SkipWrap();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
SaveCurrent(provider);
provider.start();
//если метка уже бывала. значит больше меток нет
if (provider.label_flag) {
provider.setType(Token.IDENTIFIER);
} else {
provider.setType(Token.MARKUP_TAG_NAME);
provider.label_flag = true;
}
break;
case '!':
SaveCurrent(provider);
provider.start();
//комментарий. анализ закончен
provider.setType(Token.COMMENT_EOL);
provider.stop();
break;
default:
SaveCurrent(provider);
provider.start();
provider.setType(Token.IDENTIFIER);
break;
}
break;
case Token.IDENTIFIER:
switch (provider.c) {
case '!':
SaveCurrent(provider);
provider.start();
//комментарий. анализ закончен
provider.setType(Token.COMMENT_EOL);
provider.stop();
break;
case '\t':
SaveCurrent(provider);
provider.start();
provider.SkipWrap();
break;
default:
//уже неважно что это.
break;
}
break;
}
break;
case 5:
switch (provider.c) {
case ' ':
case '\r':
case '\t':
switch (provider.currentTokenType) {
case Token.WHITESPACE:
//это пробел, и нам норм.
break;
default:
SaveCurrent(provider);
provider.start();
provider.setType(Token.WHITESPACE);
break;
}
//это пробелы. переноса нет. убираем сохранение типа
provider.startTokenType = Token.NULL;
break;
default:
//это - позиция переноса. сохраняем все что было до нее.
SaveCurrent(provider);
provider.start();
provider.setType(Token.OPERATOR);
SaveCurrent_(provider); //сохраняем его как одиночный оператор.
provider.setType(provider.startTokenType);
//берем унаследование от предыдущей строки
break;
}
break;
//</editor-fold>
//<editor-fold desc="Основной текст строки">
default:
switch (provider.currentTokenType) {
case Token.NULL:
provider.start();
provider.detectType();
break;
case Token.WHITESPACE:
switch (provider.c) {
case ' ':
case '\t':
case '\r':
break;
default:
SaveCurrent(provider);
provider.start();
provider.detectType();
break;
}
break;
case Token.OPERATOR:
provider.checkWrap();
SaveCurrent(provider);
provider.start();
provider.detectType();
break;
case Token.LITERAL_NUMBER_DECIMAL_INT:
provider.checkWrap();
switch (provider.c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '\r':
break;
case '.':
case 'e':
case 'E':
case 'd':
case 'D':
provider.setType(Token.LITERAL_NUMBER_FLOAT);
break;
default:
SaveCurrent(provider);
provider.start();
provider.detectType();
break;
}
break;
case Token.LITERAL_NUMBER_FLOAT:
provider.checkWrap();
switch (provider.c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '\r':
break;
case 'e':
case 'E':
case 'd':
case 'D':
SaveCurrent_(provider);
provider.setType(Token.NULL);
break;
default:
SaveCurrent(provider);
provider.start();
provider.detectType();
break;
}
break;
case Token.RESERVED_WORD_2:
provider.checkWrap();
switch (provider.c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
//подозрения подтвердились. это дробь.
provider.setType(Token.LITERAL_NUMBER_FLOAT);
break;
case '\r':
break;
default:
provider.setType(Token.IDENTIFIER);
break;
}
break;
case Token.LITERAL_CHAR:
switch (provider.c) {
case '\'':
SaveCurrent_(provider);
provider.setType(Token.NULL);
break;
default:
break;
}
break;
case Token.LITERAL_STRING_DOUBLE_QUOTE:
switch (provider.c) {
case '"':
SaveCurrent_(provider);
provider.setType(Token.NULL);
break;
default:
break;
}
break;
case Token.IDENTIFIER:
provider.checkWrap();
if (!
(RSyntaxUtilities.isLetter(provider.c) ||
RSyntaxUtilities.isDigit(provider.c) ||
(provider.c == '_') ||
(provider.c == '.')
)) {
SaveCurrent(provider);
provider.start();
provider.detectType();
}
break;
}
//</editor-fold>
}
}
@Override
public void performFinish(TokenProvider provider) {
switch (provider.currentTokenType) {
case Token.NULL:
addNullToken();
break;
// case Token.IDENTIFIER:
case Token.LITERAL_NUMBER_DECIMAL_INT:
case Token.LITERAL_NUMBER_FLOAT:
case Token.RESERVED_WORD_2:
SaveCurrent(provider);
break;
default:
SaveCurrent(provider);
addNullToken();
break;
}
}
}