refactor: обновление грамматики языка Ъ+ (операторы, литералы, токены)
This commit is contained in:
25
src/dfa.rs
25
src/dfa.rs
@@ -48,10 +48,8 @@ pub enum DfaState {
|
||||
LogicalAndCandidate,
|
||||
/// Состояние обработки логического ИЛИ/битового ИЛИ (после `|`)
|
||||
LogicalOrCandidate,
|
||||
/// Состояние обработки оператора мутации (после `:`)
|
||||
MutateCandidate,
|
||||
/// Состояние обработки оператора возведения в степень (после первой `*`)
|
||||
PowerCandidate,
|
||||
/// Состояние обработки оператора цикла (после `?`)
|
||||
LoopCandidate,
|
||||
|
||||
// Состояния литералов
|
||||
/// Состояние обработки десятичного числового литерала
|
||||
@@ -141,19 +139,24 @@ impl DfaState {
|
||||
(DfaState::Initial, '&', false) => DfaState::LogicalAndCandidate,
|
||||
(DfaState::Initial, '"', false) => DfaState::StringLiteral,
|
||||
(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::Accept,
|
||||
|
||||
// Переходы для операторов (упрощенные)
|
||||
(DfaState::PipelineCandidate, '>', false) => DfaState::Accept,
|
||||
(DfaState::WriteOrShiftLeftCandidate, '<', false) => DfaState::Accept,
|
||||
(DfaState::EqualOrAssignCandidate, '=', false) => DfaState::Accept,
|
||||
(DfaState::NotEqualCandidate, '=', false) => DfaState::Accept,
|
||||
(DfaState::LogicalAndCandidate, '&', false) => DfaState::Accept,
|
||||
(DfaState::LogicalOrCandidate, '|', false) => DfaState::Accept,
|
||||
(DfaState::PowerCandidate, '*', false) => DfaState::Accept,
|
||||
(DfaState::PipelineCandidate, '>', false) => DfaState::Accept, // `|>`
|
||||
(DfaState::WriteOrShiftLeftCandidate, '<', false) => DfaState::ShiftLeftSecondChar, // второй `<` для `<<<` или `<<`
|
||||
(DfaState::ShiftLeftSecondChar, '<', false) => DfaState::Accept, // `<<<` (сдвиг влево)
|
||||
// TODO: Обработать `<<` (запись в буфер) - это должно быть отдельное состояние
|
||||
(DfaState::ShiftRightCandidate, '>', false) => DfaState::ShiftRightSecondChar, // второй `>` для `>>>`
|
||||
(DfaState::ShiftRightSecondChar, '>', 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,
|
||||
}
|
||||
|
||||
@@ -59,17 +59,25 @@ pub const OP_BITWISE_AND: char = '&';
|
||||
pub const OP_BITWISE_OR: char = '|';
|
||||
pub const OP_BITWISE_XOR: 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_MUTATE: &str = ":=";
|
||||
|
||||
/// Специальные символы
|
||||
pub const ARROW: &str = "->";
|
||||
pub const COMMA: 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";
|
||||
@@ -78,8 +86,16 @@ pub const BINARY_PREFIX: &str = "0b";
|
||||
/// Разделитель разрядов в числовых литералах
|
||||
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
|
||||
}
|
||||
|
||||
/// Проверяет, является ли символ оператором присваивания или мутации.
|
||||
/// Проверяет, является ли символ оператором присваивания.
|
||||
pub fn is_assignment_operator(ch: char) -> bool {
|
||||
ch == OP_ASSIGN
|
||||
}
|
||||
|
||||
/// Проверяет, является ли строка оператором мутации.
|
||||
pub fn is_mutate_operator(s: &str) -> bool {
|
||||
s == OP_MUTATE
|
||||
}
|
||||
|
||||
/// Проверяет, является ли символ началом числового литерала.
|
||||
pub fn is_digit_start(ch: char) -> bool {
|
||||
ch.is_ascii_digit()
|
||||
@@ -243,9 +254,14 @@ pub fn is_pipeline_or_write_start(ch: char) -> bool {
|
||||
matches!(ch, '|' | '<')
|
||||
}
|
||||
|
||||
/// Проверяет, является ли символ оператором цикла.
|
||||
pub fn is_loop_operator(ch: char) -> bool {
|
||||
ch == LOOP_OP
|
||||
/// Проверяет, является ли символ началом оператора цикла.
|
||||
pub fn is_loop_operator_start(ch: char) -> bool {
|
||||
ch == PREDICATE_PREFIX
|
||||
}
|
||||
|
||||
/// Проверяет, является ли строка оператором цикла (`?*`).
|
||||
pub fn is_loop_operator(s: &str) -> bool {
|
||||
s == LOOP_OP
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -258,5 +274,9 @@ mod tests {
|
||||
// - Тест is_comment_start_char
|
||||
// - Тест is_comment_end_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 префиксов
|
||||
}
|
||||
|
||||
|
||||
26
src/token.rs
26
src/token.rs
@@ -23,9 +23,9 @@ pub enum TokenKind {
|
||||
BlockEnd,
|
||||
/// Оператор конвейера (`|>`)
|
||||
PipelineOperator,
|
||||
/// Оператор записи (`<<`)
|
||||
/// Оператор записи в буфер (`<<`)
|
||||
WriteOperator,
|
||||
/// Цикл (`>`)
|
||||
/// Оператор цикла (`?*`)
|
||||
LoopOperator,
|
||||
|
||||
// Арифметические операторы
|
||||
@@ -39,8 +39,6 @@ pub enum TokenKind {
|
||||
Divide,
|
||||
/// Остаток от деления (`%`)
|
||||
Modulo,
|
||||
/// Возведение в степень (`**`)
|
||||
Power,
|
||||
|
||||
// Операторы сравнения
|
||||
/// Равенство (`==`)
|
||||
@@ -73,16 +71,14 @@ pub enum TokenKind {
|
||||
BitwiseXor,
|
||||
/// Битовое НЕ (`~`)
|
||||
BitwiseNot,
|
||||
/// Сдвиг влево (`<<`)
|
||||
/// Сдвиг влево (`<<<`)
|
||||
ShiftLeft,
|
||||
/// Сдвиг вправо (`>>`)
|
||||
/// Сдвиг вправо (`>>>`)
|
||||
ShiftRight,
|
||||
|
||||
// Операторы присваивания
|
||||
/// Присваивание (`=`)
|
||||
Assign,
|
||||
/// Мутация (`:=`)
|
||||
Mutate,
|
||||
|
||||
// Литералы
|
||||
/// Целочисленный литерал
|
||||
@@ -121,6 +117,14 @@ pub enum TokenKind {
|
||||
RightBracket,
|
||||
/// Стрелка (`->`)
|
||||
Arrow,
|
||||
/// Точка (доступ к полям) (`.`)
|
||||
Dot,
|
||||
|
||||
// Структура программы
|
||||
/// Определение типа (`!:ТИП`)
|
||||
TypeDefinition,
|
||||
/// Определение константы (`!:КОНСТ`)
|
||||
ConstantDefinition,
|
||||
|
||||
// Конструкции (для парсера)
|
||||
/// Сопоставление с образцом (match)
|
||||
@@ -234,7 +238,6 @@ impl Token {
|
||||
| TokenKind::Multiply
|
||||
| TokenKind::Divide
|
||||
| TokenKind::Modulo
|
||||
| TokenKind::Power
|
||||
| TokenKind::Equal
|
||||
| TokenKind::NotEqual
|
||||
| TokenKind::Less
|
||||
@@ -251,7 +254,6 @@ impl Token {
|
||||
| TokenKind::ShiftLeft
|
||||
| TokenKind::ShiftRight
|
||||
| TokenKind::Assign
|
||||
| TokenKind::Mutate
|
||||
)
|
||||
}
|
||||
|
||||
@@ -290,7 +292,9 @@ mod tests {
|
||||
// TODO: Написать тесты для Token
|
||||
// - Тест создания токена
|
||||
// - Тест is_identifier
|
||||
// - Тест is_operator
|
||||
// - Тест is_operator (включая новые операторы: <<<, >>>, ?*)
|
||||
// - Тест identifier_text
|
||||
// - Тест типизированных литералов с кириллическими суффиксами (б8, ц8, бр, цр, в32 и т.д.)
|
||||
// - Тест операторов TypeDefinition и ConstantDefinition
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user