refactor: обновление грамматики языка Ъ+ (операторы, литералы, токены)

This commit is contained in:
ShishkaDanil
2026-01-03 20:02:11 +03:00
parent 06164cff09
commit 8717e975b5
3 changed files with 63 additions and 36 deletions

View File

@@ -48,10 +48,8 @@ pub enum DfaState {
LogicalAndCandidate, LogicalAndCandidate,
/// Состояние обработки логического ИЛИ/битового ИЛИ (после `|`) /// Состояние обработки логического ИЛИ/битового ИЛИ (после `|`)
LogicalOrCandidate, LogicalOrCandidate,
/// Состояние обработки оператора мутации (после `:`) /// Состояние обработки оператора цикла (после `?`)
MutateCandidate, LoopCandidate,
/// Состояние обработки оператора возведения в степень (после первой `*`)
PowerCandidate,
// Состояния литералов // Состояния литералов
/// Состояние обработки десятичного числового литерала /// Состояние обработки десятичного числового литерала
@@ -141,19 +139,24 @@ impl DfaState {
(DfaState::Initial, '&', false) => DfaState::LogicalAndCandidate, (DfaState::Initial, '&', false) => DfaState::LogicalAndCandidate,
(DfaState::Initial, '"', false) => DfaState::StringLiteral, (DfaState::Initial, '"', false) => DfaState::StringLiteral,
(DfaState::Initial, '0'..='9', false) => DfaState::DecimalLiteral, (DfaState::Initial, '0'..='9', false) => DfaState::DecimalLiteral,
(DfaState::Initial, '.', false) => DfaState::Accept, // Доступ к полям
(DfaState::Initial, '+', false) | (DfaState::Initial, '-', false) | (DfaState::Initial, '+', false) | (DfaState::Initial, '-', false) |
(DfaState::Initial, '*', false) | (DfaState::Initial, '/', false) | (DfaState::Initial, '*', false) | (DfaState::Initial, '/', false) |
(DfaState::Initial, '%', false) | (DfaState::Initial, '^', false) | (DfaState::Initial, '%', false) | (DfaState::Initial, '^', false) |
(DfaState::Initial, '~', false) => DfaState::Accept, (DfaState::Initial, '~', false) => DfaState::Accept,
// Переходы для операторов (упрощенные) // Переходы для операторов (упрощенные)
(DfaState::PipelineCandidate, '>', false) => DfaState::Accept, (DfaState::PipelineCandidate, '>', false) => DfaState::Accept, // `|>`
(DfaState::WriteOrShiftLeftCandidate, '<', false) => DfaState::Accept, (DfaState::WriteOrShiftLeftCandidate, '<', false) => DfaState::ShiftLeftSecondChar, // второй `<` для `<<<` или `<<`
(DfaState::EqualOrAssignCandidate, '=', false) => DfaState::Accept, (DfaState::ShiftLeftSecondChar, '<', false) => DfaState::Accept, // `<<<` (сдвиг влево)
(DfaState::NotEqualCandidate, '=', false) => DfaState::Accept, // TODO: Обработать `<<` (запись в буфер) - это должно быть отдельное состояние
(DfaState::LogicalAndCandidate, '&', false) => DfaState::Accept, (DfaState::ShiftRightCandidate, '>', false) => DfaState::ShiftRightSecondChar, // второй `>` для `>>>`
(DfaState::LogicalOrCandidate, '|', false) => DfaState::Accept, (DfaState::ShiftRightSecondChar, '>', false) => DfaState::Accept, // `>>>`
(DfaState::PowerCandidate, '*', false) => DfaState::Accept, (DfaState::EqualOrAssignCandidate, '=', false) => DfaState::Accept, // `==`
(DfaState::NotEqualCandidate, '=', false) => DfaState::Accept, // `!=`
(DfaState::LogicalAndCandidate, '&', false) => DfaState::Accept, // `&&`
(DfaState::LogicalOrCandidate, '|', false) => DfaState::Accept, // `||`
(DfaState::LoopCandidate, '*', false) => DfaState::Accept, // `?*` (цикл)
_ => DfaState::Error, _ => DfaState::Error,
} }

View File

@@ -59,17 +59,25 @@ pub const OP_BITWISE_AND: char = '&';
pub const OP_BITWISE_OR: char = '|'; pub const OP_BITWISE_OR: char = '|';
pub const OP_BITWISE_XOR: char = '^'; pub const OP_BITWISE_XOR: char = '^';
pub const OP_BITWISE_NOT: char = '~'; pub const OP_BITWISE_NOT: char = '~';
pub const OP_SHIFT_LEFT: &str = "<<"; /// Сдвиг влево (три символа `<`)
pub const OP_SHIFT_RIGHT: &str = ">>"; pub const OP_SHIFT_LEFT: &str = "<<<";
/// Сдвиг вправо (три символа `>`)
pub const OP_SHIFT_RIGHT: &str = ">>>";
/// Операторы присваивания /// Операторы присваивания
pub const OP_ASSIGN: char = '='; pub const OP_ASSIGN: char = '=';
pub const OP_MUTATE: &str = ":=";
/// Специальные символы /// Специальные символы
pub const ARROW: &str = "->"; pub const ARROW: &str = "->";
pub const COMMA: char = ','; pub const COMMA: char = ',';
pub const SEMICOLON: char = ';'; pub const SEMICOLON: char = ';';
pub const DOT: char = '.';
/// Структура программы
/// Префикс определения типа
pub const TYPE_DEF_PREFIX: &str = "!:ТИП";
/// Префикс определения константы
pub const CONST_DEF_PREFIX: &str = "!:КОНСТ";
/// Префиксы числовых литералов /// Префиксы числовых литералов
pub const HEX_PREFIX: &str = "0x"; pub const HEX_PREFIX: &str = "0x";
@@ -78,8 +86,16 @@ pub const BINARY_PREFIX: &str = "0b";
/// Разделитель разрядов в числовых литералах /// Разделитель разрядов в числовых литералах
pub const DIGIT_SEPARATOR: char = '_'; pub const DIGIT_SEPARATOR: char = '_';
/// Допустимые типы для литералов /// Допустимые типы для литералов (кириллические суффиксы)
pub const TYPE_SUFFIXES: &[&str] = &["u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64"]; /// б8, ц8, б16, ц16, б32, ц32, б64, ц64, бр, цр, в32, в64
pub const TYPE_SUFFIXES: &[&str] = &[
"б8", "ц8", // беззнаковое/знаковое 8-битное
"б16", "ц16", // беззнаковое/знаковое 16-битное
"б32", "ц32", // беззнаковое/знаковое 32-битное
"б64", "ц64", // беззнаковое/знаковое 64-битное
"бр", "цр", // беззнаковое/знаковое размер указателя
"в32", "в64", // вещественное 32/64-битное
];
/// Проверяет, является ли символ префиксом идентификатора. /// Проверяет, является ли символ префиксом идентификатора.
/// ///
@@ -203,16 +219,11 @@ pub fn is_assignment_op_start(ch: char) -> bool {
ch == OP_ASSIGN || ch == LABEL_PREFIX ch == OP_ASSIGN || ch == LABEL_PREFIX
} }
/// Проверяет, является ли символ оператором присваивания или мутации. /// Проверяет, является ли символ оператором присваивания.
pub fn is_assignment_operator(ch: char) -> bool { pub fn is_assignment_operator(ch: char) -> bool {
ch == OP_ASSIGN ch == OP_ASSIGN
} }
/// Проверяет, является ли строка оператором мутации.
pub fn is_mutate_operator(s: &str) -> bool {
s == OP_MUTATE
}
/// Проверяет, является ли символ началом числового литерала. /// Проверяет, является ли символ началом числового литерала.
pub fn is_digit_start(ch: char) -> bool { pub fn is_digit_start(ch: char) -> bool {
ch.is_ascii_digit() ch.is_ascii_digit()
@@ -243,9 +254,14 @@ pub fn is_pipeline_or_write_start(ch: char) -> bool {
matches!(ch, '|' | '<') matches!(ch, '|' | '<')
} }
/// Проверяет, является ли символ оператором цикла. /// Проверяет, является ли символ началом оператора цикла.
pub fn is_loop_operator(ch: char) -> bool { pub fn is_loop_operator_start(ch: char) -> bool {
ch == LOOP_OP ch == PREDICATE_PREFIX
}
/// Проверяет, является ли строка оператором цикла (`?*`).
pub fn is_loop_operator(s: &str) -> bool {
s == LOOP_OP
} }
#[cfg(test)] #[cfg(test)]
@@ -258,5 +274,9 @@ mod tests {
// - Тест is_comment_start_char // - Тест is_comment_start_char
// - Тест is_comment_end_char // - Тест is_comment_end_char
// - Тест is_identifier_char (кириллица, латиница, цифры) // - Тест is_identifier_char (кириллица, латиница, цифры)
// - Тест is_loop_operator_start и is_loop_operator (цикл `?*`)
// - Тест is_type_suffix (кириллические суффиксы: б8, ц8, б16, ц16, б32, ц32, б64, ц64, бр, цр, в32, в64)
// - Тест операторов сдвига (<<<, >>>)
// - Тест TypeDefinition и ConstantDefinition префиксов
} }

View File

@@ -23,9 +23,9 @@ pub enum TokenKind {
BlockEnd, BlockEnd,
/// Оператор конвейера (`|>`) /// Оператор конвейера (`|>`)
PipelineOperator, PipelineOperator,
/// Оператор записи (`<<`) /// Оператор записи в буфер (`<<`)
WriteOperator, WriteOperator,
/// Цикл (`>`) /// Оператор цикла (`?*`)
LoopOperator, LoopOperator,
// Арифметические операторы // Арифметические операторы
@@ -39,8 +39,6 @@ pub enum TokenKind {
Divide, Divide,
/// Остаток от деления (`%`) /// Остаток от деления (`%`)
Modulo, Modulo,
/// Возведение в степень (`**`)
Power,
// Операторы сравнения // Операторы сравнения
/// Равенство (`==`) /// Равенство (`==`)
@@ -73,16 +71,14 @@ pub enum TokenKind {
BitwiseXor, BitwiseXor,
/// Битовое НЕ (`~`) /// Битовое НЕ (`~`)
BitwiseNot, BitwiseNot,
/// Сдвиг влево (`<<`) /// Сдвиг влево (`<<<`)
ShiftLeft, ShiftLeft,
/// Сдвиг вправо (`>>`) /// Сдвиг вправо (`>>>`)
ShiftRight, ShiftRight,
// Операторы присваивания // Операторы присваивания
/// Присваивание (`=`) /// Присваивание (`=`)
Assign, Assign,
/// Мутация (`:=`)
Mutate,
// Литералы // Литералы
/// Целочисленный литерал /// Целочисленный литерал
@@ -121,6 +117,14 @@ pub enum TokenKind {
RightBracket, RightBracket,
/// Стрелка (`->`) /// Стрелка (`->`)
Arrow, Arrow,
/// Точка (доступ к полям) (`.`)
Dot,
// Структура программы
/// Определение типа (`!:ТИП`)
TypeDefinition,
/// Определение константы (`!:КОНСТ`)
ConstantDefinition,
// Конструкции (для парсера) // Конструкции (для парсера)
/// Сопоставление с образцом (match) /// Сопоставление с образцом (match)
@@ -234,7 +238,6 @@ impl Token {
| TokenKind::Multiply | TokenKind::Multiply
| TokenKind::Divide | TokenKind::Divide
| TokenKind::Modulo | TokenKind::Modulo
| TokenKind::Power
| TokenKind::Equal | TokenKind::Equal
| TokenKind::NotEqual | TokenKind::NotEqual
| TokenKind::Less | TokenKind::Less
@@ -251,7 +254,6 @@ impl Token {
| TokenKind::ShiftLeft | TokenKind::ShiftLeft
| TokenKind::ShiftRight | TokenKind::ShiftRight
| TokenKind::Assign | TokenKind::Assign
| TokenKind::Mutate
) )
} }
@@ -290,7 +292,9 @@ mod tests {
// TODO: Написать тесты для Token // TODO: Написать тесты для Token
// - Тест создания токена // - Тест создания токена
// - Тест is_identifier // - Тест is_identifier
// - Тест is_operator // - Тест is_operator (включая новые операторы: <<<, >>>, ?*)
// - Тест identifier_text // - Тест identifier_text
// - Тест типизированных литералов с кириллическими суффиксами (б8, ц8, бр, цр, в32 и т.д.)
// - Тест операторов TypeDefinition и ConstantDefinition
} }