/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package ru.malik.elaborarer.avtoo.compiler;
import ru.malik.elaborarer.avtoo.lang.*;
public class DocumentLexer(Lexer, AVTOOConstants)
{
private static final char[] symbols;
private static final String[] lexemes;
private static {
symbols = ".,`=()[]{}<>!~&^|+-*/%#@".toCharArray();
lexemes = new String[D_LEXEMES_LENGTH];
lexemes[D_ALINK ] = "@link";
lexemes[D_APARAM ] = "@param";
lexemes[D_ARETURN ] = "@return";
lexemes[D_ATHROWS ] = "@throws";
lexemes[D_ASINCE ] = "@since";
lexemes[D_ASEE ] = "@see";
lexemes[D_SCAL_DIVU ] = "//";
lexemes[D_SCAL_REMU ] = "%%";
lexemes[D_SCAL_SHR ] = ">>";
lexemes[D_SCAL_SHRU ] = ">>>";
lexemes[D_SCAL_SHL ] = "<<";
lexemes[D_SCAL_GE ] = ">=";
lexemes[D_SCAL_LE ] = "<=";
lexemes[D_SCAL_EQ ] = "==";
lexemes[D_SCAL_NE ] = "!=";
lexemes[D_VECT_LUP ] = "####";
lexemes[D_VECT_UUP ] = "^^^^";
lexemes[D_VECT_PCK ] = "@@@@";
lexemes[D_VECT_MUL ] = "****";
lexemes[D_VECT_DIV ] = "////";
lexemes[D_VECT_ADD ] = "++++";
lexemes[D_VECT_SUB ] = "----";
lexemes[D_VECT_SHR ] = ">>>>";
lexemes[D_VECT_SHRU ] = ">>>>>";
lexemes[D_VECT_SHL ] = "<<<<";
lexemes[D_VECT_GT ] = "|>>|";
lexemes[D_VECT_GE ] = "|>=|";
lexemes[D_VECT_LT ] = "|<<|";
lexemes[D_VECT_LE ] = "|<=|";
lexemes[D_VECT_EQ ] = "|==|";
lexemes[D_VECT_NE ] = "|!=|";
lexemes[D_VECT_HMUL ] = "|**|";
lexemes[D_VECT_HMULU ] = "#**#";
lexemes[D_VECT_SADD ] = "|++|";
lexemes[D_VECT_SADDU ] = "#++#";
lexemes[D_VECT_SSUB ] = "|--|";
lexemes[D_VECT_SSUBU ] = "#--#";
lexemes[D_PARENTH_OPENED] = "(";
lexemes[D_PARENTH_CLOSED] = ")";
lexemes[D_BRACKET_OPENED] = "[";
lexemes[D_BRACKET_CLOSED] = "]";
lexemes[D_CURLY_OPENED ] = "{";
lexemes[D_CURLY_CLOSED ] = "}";
lexemes[D_TAG_OPENED ] = "<";
lexemes[D_TAG_CLOSED ] = ">";
lexemes[D_EQUALS ] = "=";
lexemes[D_GRAVE_ACCENT ] = "`";
lexemes[D_PERIOD ] = ".";
lexemes[D_COMMA ] = ",";
lexemes[D_EXCLAM_MARK ] = "!";
lexemes[D_VERTICAL_LINE ] = "|";
lexemes[D_AMPERSAND ] = "&";
lexemes[D_TILDE ] = "~";
lexemes[D_POUND_SIGN ] = "#";
lexemes[D_CIRCUMFLEX_ACC] = "^";
lexemes[D_ASTERISK ] = "*";
lexemes[D_SOLIDUS ] = "/";
lexemes[D_PERCENT ] = "%";
lexemes[D_PLUS ] = "+";
lexemes[D_MINUS ] = "-";
lexemes[D_AT ] = "@";
}
private static int parseChar(int lineIndex, char[] line, int charIndex, char chr, LexemeSequence sequence) {
if(Array.indexOf(chr, symbols, 0, 0) < 0) return charIndex;
int result = charIndex + 1;
int length = 1;
for(chr = line[result]; length < 7 && (Array.indexOf(chr, symbols, 0, 0) >= 0 || chr >= 'a' && chr <= 'z'); length++) chr = line[++result];
label0: for(; length > 0; result--, length--) for(int index = D_LEXEMES_LENGTH; (index = Array.lastIndexOfNon(null, lexemes, index - 1, 0)) >= 0; )
{
String lexeme = lexemes[index];
if(lexeme.length == length && lexeme.contentEquals(line, charIndex))
{
sequence.appendLexeme(lineIndex, charIndex, index, lexeme);
break label0;
}
}
return result;
}
private static int parseName(int lineIndex, char[] line, int charIndex, char chr, LexemeSequence sequence) {
if((chr < 'A' || chr > 'Z') && (chr < 'a' || chr > 'z') && (chr != '_')) return charIndex;
int result = charIndex + 1;
for(; (chr = line[result]) >= 'A' && chr <= 'Z' || chr >= 'a' && chr <= 'z' || chr >= '0' && chr <= '9' || chr == '_'; result++);
sequence.appendLexeme(lineIndex, charIndex, D_NAME, new String(line, charIndex, result - charIndex));
return result;
}
private static int parseText(int lineIndex, char[] line, int charIndex, char chr, LexemeSequence sequence) {
if(chr <= 0) return charIndex;
int result = charIndex + 1;
for(; (chr = line[result]) > 0x20 && Array.indexOf(chr, symbols, 0, 0) < 0 && (chr < 'A' || chr > 'Z') && (chr < 'a' || chr > 'z') && (chr != '_'); result++);
sequence.appendLexeme(lineIndex, charIndex, D_TEXT, new String(line, charIndex, result - charIndex));
return result;
}
protected boolean fldLineEndingEnabled;
public () { }
public void split(char[][] text, int2 locationBegin, int2 locationEnd, LexemeSequence sequence) {
if(text == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "text" }));
}
if(sequence == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "sequence" }));
}
int limit = text.length;
if(limit-- <= 0)
{
sequence.appendLexeme(0, 0, D_END);
return;
}
int lineIndexBegin = locationBegin[0];
int charIndexBegin = locationBegin[1];
int lineIndexEnd = locationEnd[0];
int charIndexEnd = locationEnd[1];
int count = text[limit].length - 1;
if(lineIndexBegin < 0)
{
lineIndexBegin = 0;
charIndexBegin = 0;
}
if(lineIndexBegin > limit)
{
lineIndexBegin = limit;
charIndexBegin = count;
}
if(lineIndexEnd < 0)
{
lineIndexEnd = 0;
charIndexEnd = 0;
}
if(lineIndexEnd > limit)
{
lineIndexEnd = limit;
charIndexEnd = count;
}
if(charIndexBegin < 0)
{
charIndexBegin = 0;
}
if(charIndexBegin > (count = text[lineIndexBegin].length - 1))
{
charIndexBegin = count;
}
if(charIndexEnd < 0)
{
charIndexEnd = 0;
}
if(charIndexEnd > (count = text[lineIndexEnd].length - 1))
{
charIndexEnd = count;
}
char[] last = text[lineIndexEnd];
if(charIndexEnd < last.length - 1)
{
Array.copy(last, 0, last = new char[charIndexEnd + 1], 0, charIndexEnd);
}
for(boolean lineEndingEnabled = fldLineEndingEnabled, int lineIndex = lineIndexBegin; lineIndex <= lineIndexEnd; lineIndex++)
{
char chr;
int charIndex = lineIndex <= lineIndexBegin ? charIndexBegin : 0;
char[] line = lineIndex >= lineIndexEnd ? last : text[lineIndex];
while((chr = line[charIndex]) > 0x00 && chr <= 0x20) charIndex++;
if(chr == '*') chr = line[++charIndex];
boolean empty = true;
while(chr > 0x00)
{
if(chr <= 0x20) do
{
charIndex++;
} while((chr = line[charIndex]) > 0x00 && chr <= 0x20);
if(
charIndex < (charIndex = parseChar(lineIndex, line, charIndex, chr, sequence)) ||
charIndex < (charIndex = parseName(lineIndex, line, charIndex, chr, sequence)) ||
charIndex < (charIndex = parseText(lineIndex, line, charIndex, chr, sequence))
)
{
chr = line[charIndex];
empty = false;
}
}
if(empty)
{
sequence.appendLexeme(lineIndex, charIndex, D_EOP);
}
else if(lineEndingEnabled)
{
sequence.appendLexeme(lineIndex, charIndex, D_EOL);
}
}
sequence.appendLexeme(lineIndexEnd, charIndexEnd, D_END);
}
public boolean lineEndingEnabled { read = fldLineEndingEnabled, write = fldLineEndingEnabled }
}