package Common.UI.Themes; import org.fife.ui.rsyntaxtextarea.Token; import javax.swing.text.Segment; //сткуртура контейнер для всех текущих переменных. //для упрощения операций. public class TokenProvider { public Segment text; public char[] array; public int offset; public int count; public int end; // Token starting offsets are always of the form: // 'startOffset + (currentTokenStart-offset)', but since startOffset and // offset are constant, tokens' starting positions become: // 'newStartOffset+currentTokenStart'. public int newStartOffset; public int currentTokenStart; public int startTokenType; //хранить тип токена который нам передали, ради переносов public int currentTokenType; public int i; public int position; public char c; public boolean label_flag; public TokenProvider(Segment text_in, int startTokenType_in, int startOffset) { text = text_in; startTokenType = startTokenType_in; //может указывать на то, что мы продолжаем. array = text.array; offset = text.offset; count = text.count; end = offset + count; // Token starting offsets are always of the form: // 'startOffset + (currentTokenStart-offset)', but since startOffset and // offset are constant, tokens' starting positions become: // 'newStartOffset+currentTokenStart'. newStartOffset = startOffset - offset; currentTokenStart = offset; currentTokenType = Token.NULL; //изначально не знаем что будем обрабатывать. position = 0; i = offset; label_flag = false; } public void checkWrap() { if (startTokenType != Token.NULL) { start(); startTokenType = Token.NULL; } } public void readNext() { c = array[i]; } public void gotoNext() { ++i; ++position; //todo от греха от табов надо избавляться. // возникает расхожедние между реальным и табским смещением. отсюда галюны. // лучше бы их не отображать даже если они есть. но это к тексту файла. или как то узнавать их длину.. } public boolean canRead() { return i < end; } public void setType(int currentTokenType_in) { currentTokenType = currentTokenType_in; } public void stop() { i = end - 1; } public void start() { currentTokenStart = i; } //в зоне основной строки //по текущему символу определяем тип уже начатого токена. public void detectType() { switch (c) { case ' ': case '\t': case '\r': currentTokenType = Token.WHITESPACE; break; case '+': case '-': case '*': case '/': case '=': case '(': case ')': case '[': case ']': case '<': case '>': case '{': case '}': case ',': case '&': currentTokenType = Token.OPERATOR; break; case '\'': currentTokenType = Token.LITERAL_CHAR; break; case '"': currentTokenType = Token.LITERAL_STRING_DOUBLE_QUOTE; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': currentTokenType = Token.LITERAL_NUMBER_DECIMAL_INT; break; case '.': //возможный кандидат на число с плавающей точкой. currentTokenType = Token.RESERVED_WORD_2; break; case '!': currentTokenType = Token.COMMENT_EOL; stop(); break; default: currentTokenType = Token.IDENTIFIER; break; } } //досрочный выход из зоны переноса. public void SkipWrap() { startTokenType = Token.NULL; //перенос исключается. position += 6; //гарантированное непопадание в зону переноса при анализе. setType(Token.WHITESPACE); //стоит таб, значит переноса не будет. идет набор пробелов. } }