bayrell / BayLang

BayLang compiler source code
https://bayrell.org/ru/docs/baylang
Apache License 2.0
4 stars 0 forks source link

Идея парсера #139

Open ildar-ceo opened 7 months ago

ildar-ceo commented 7 months ago

Нужно ввести:

Caret current_caret;
ParserState state;

BaseOpCode op_code = ParserExpression::parse(current_caret, state);
BaseOpCode op_code = ParserCss::parse(current_caret, state);

Идея в том, что вызывается статическая функция ParserExpression::parse которая умеет парсить с текущего положения и возвращает op коды. Также двигает каретку и state.

Данные state и каретка должны легко копироваться методом clone

ildar-ceo commented 7 months ago

Таким образом можно создать различные парсеры, такие как:

Также планируется, что эти парсеры смогут вызывать друг друга.

ildar-ceo commented 7 months ago

Каретки могут быть разных типов. Например, каретки для HTML или BayLang. Задача кареток следить за текущей позицией в файле и возвращать следующие токены. Также каретки должны обладать методом seek который двигает каретку в позицию другой каретки.

Пример использования кареток:

/**
 * Parse HTML
 */
void parse(Caret current_caret, ParserState state)
{
    Caret caret_html = current_caret;

    if (caret_html instanceof CaretHTML)
    {
        caret_html = CaretHTML::from(current_caret);
    }

    BaseOpCode op_code = static::readHTML(caret_html, state);

    if (current_caret != caret_html)
    {
        current_caret.seek(caret_html);
    }

    return op_code;
}

BaseOpCode op_code_html = ParserHTML::parse(current_caret, state);
ildar-ceo commented 7 months ago

С помощью таких кареток можно разрабатывать функции проверки. Является ли следующий код функцией, переменной и т.п.

ildar-ceo commented 7 months ago

Также токены должны содержать информацию pos_start, pos_end, x, y.

ildar-ceo commented 7 months ago

Скорее всего нужно два класса:

ildar-ceo commented 7 months ago

Функция получить следующий токен:

Caret caret_look = Caret::from(caret);

/* ... */

caret_look.seek(caret);
token = caret_look.readToken();

if (token == "test")
{
   caret.seek(caret_look);
   /* Do something */
}

Прочитать токен:

token = caret.readToken();

Проверить следующий токен:

token = caret.matchToken("test");