DocumentLexer.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Компилятор языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    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 }
}