Модуль ../src/parser.rs реализует синтаксический анализатор (парсер) для языка SOFIA. Парсер принимает на вход последовательность токенов, сгенерированных лексером, и строит Абстрактное Синтаксическое Дерево (AST), которое является иерархическим представлением исходного кода. Парсер использует алгоритм "Pratt parser" для обработки выражений с учетом приоритетов операторов.
graph TD
A[Токены] --> B(Parser);
B --> C{Абстрактное Синтаксическое Дерево AST};
A -- ../src/token.rs --> B;
C -- ../src/ast.rs --> B;
Перечисление Precedence определяет приоритеты операторов в языке SOFIA. Чем выше значение, тем выше приоритет. Это критически важно для корректного построения AST выражений.
Lowest: Самый низкий приоритет.Arrow: Приоритет для оператора=>вmatchвыражениях.Or: Приоритет для логического оператора||.And: Приоритет для логического оператора&&.Equals: Приоритет для операторов сравнения==,!=.LessGreater: Приоритет для операторов сравнения<,>.Sum: Приоритет для операторов сложения и вычитания+,-.Product: Приоритет для операторов умножения, деления и модуля*,/,%.Power: Приоритет для оператора возведения в степень**.Range: Приоритет для операторов диапазона..,..=.Prefix: Приоритет для префиксных операторов-X,!X.Call: Приоритет для вызова функцийmyFunction(X).Dot: Приоритет для доступа к членам объектаobject.member.
Перечисление ParserError определяет типы ошибок, которые могут возникнуть в процессе синтаксического анализа.
UnexpectedToken(String): Возникает, когда парсер ожидает определенный токен, но получает другой.
Структура Parser хранит состояние синтаксического анализатора.
lexer:Lexer— Экземпляр лексера, используемый для получения токенов.current_token:Token— Текущий токен, который анализируется.next_token:Token— Следующий токен (для "подглядывания" вперед).errors:Vec<ParserError>— Вектор ошибок, обнаруженных в процессе парсинга.
pub fn new(lexer: Lexer) -> SelfСоздает новый экземпляр Parser. Инициализирует лексер и считывает первые два токена для заполнения current_token и next_token.
-
Параметры:
lexer:Lexer— Инициализированный лексер.
-
Возвращает:
Self(Parser) — Новый экземпляр парсера.
pub fn parse_program(&mut self) -> Result<Program, Vec<ParserError>>Основной метод парсера, который запускает процесс синтаксического анализа всей программы. Он итерируется по токенам, парсит операторы и собирает их в структуру Program.
- Возвращает:
Result<Program, Vec<ParserError>>—Ok(Program)в случае успешного парсинга илиErr(Vec<ParserError>)при наличии ошибок.
next_token(&mut self): Сдвигает токены, делаяnext_tokenтекущим, а новый токен от лексера — следующим.parse_statement(&mut self) -> Result<ast::Statement, ParserError>: Определяет тип оператора на основеcurrent_tokenи вызывает соответствующую функцию парсинга.parse_let_statement(&mut self) -> Result<ast::Statement, ParserError>: Парсит оператор объявления переменной (let).parse_return_statement(&mut self) -> Result<ast::Statement, ParserError>: Парсит оператор возврата (return).parse_expression_statement(&mut self) -> Result<ast::Statement, ParserError>: Парсит оператор, состоящий из одного выражения.parse_expression(&mut self, precedence: Precedence) -> Result<ast::Expression, ParserError>: Реализует алгоритм "Pratt parser" для парсинга выражений с учетом приоритетов.parse_prefix(&mut self) -> Result<ast::Expression, ParserError>: Парсит префиксные выражения (например, идентификаторы, литералы, унарные операторы).parse_infix(&mut self, left: ast::Expression) -> Result<ast::Expression, ParserError>: Парсит инфиксные выражения (например, бинарные операторы, вызовы функций, доступ к свойствам).parse_integer_literal(&mut self) -> Result<ast::Expression, ParserError>: Парсит целочисленные литералы.parse_string_literal(&mut self) -> Result<ast::Expression, ParserError>: Парсит строковые литералы.parse_prefix_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит префиксные операторы (!,-).parse_infix_expression(&mut self, left: ast::Expression) -> Result<ast::Expression, ParserError>: Парсит инфиксные операторы (+,-,*,/,==,!=,<,>,**,&&,||,%).parse_boolean(&mut self) -> Result<ast::Expression, ParserError>: Парсит булевы литералы (true,false).parse_grouped_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит выражения в круглых скобках.parse_array_literal(&mut self) -> Result<ast::Expression, ParserError>: Парсит литералы массивов.parse_block_statement(&mut self) -> Result<ast::BlockStatement, ParserError>: Парсит блок операторов{ ... }.parse_if_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит условное выражениеif-else.parse_function_literal(&mut self) -> Result<ast::Expression, ParserError>: Парсит литерал функцииfn(params) { body }.parse_function_parameters(&mut self) -> Result<Vec<ast::Identifier>, ParserError>: Парсит список параметров функции.parse_call_expression(&mut self, function: ast::Expression) -> Result<ast::Expression, ParserError>: Парсит вызов функции.parse_expression_list(&mut self, end: TokenType) -> Result<Vec<ast::Expression>, ParserError>: Вспомогательная функция для парсинга списков выражений (например, аргументов функции, элементов массива).parse_property_access_expression(&mut self, left: ast::Expression) -> Result<ast::Expression, ParserError>: Парсит доступ к свойству объектаobj.property.parse_new_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит выражение создания нового экземпляраnew Class().parse_this_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит выражениеthis.parse_super_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит выражениеsuper.parse_match_expression(&mut self) -> Result<ast::Expression, ParserError>: Парсит выражение сопоставления с образцомmatch.parse_class_declaration(&mut self) -> Result<ast::Statement, ParserError>: Парсит объявление класса.parse_struct_declaration(&mut self) -> Result<ast::Statement, ParserError>: Парсит объявление структуры.parse_interface_declaration(&mut self) -> Result<ast::Statement, ParserError>: Парсит объявление интерфейса.parse_access_modifier_and_static(&mut self) -> (AccessModifier, bool): Парсит модификаторы доступа (public,private) иstatic.parse_property_declaration(&mut self, access_modifier: AccessModifier, is_static: bool) -> Result<ast::PropertyDeclaration, ParserError>: Парсит объявление свойства с ключевым словомlet.parse_method_declaration(&mut self, access_modifier: AccessModifier, is_static: bool) -> Result<ast::MethodDeclaration, ParserError>: Парсит объявление метода с ключевым словомfn.parse_method_declaration_without_fn(&mut self, access_modifier: AccessModifier, is_static: bool) -> Result<ast::MethodDeclaration, ParserError>: Парсит объявление метода без ключевого словаfn.parse_property_declaration_without_let(&mut self, access_modifier: AccessModifier, is_static: bool) -> Result<ast::PropertyDeclaration, ParserError>: Парсит объявление свойства без ключевого словаlet.parse_method_signature_declaration(&mut self) -> Result<ast::MethodSignatureDeclaration, ParserError>: Парсит сигнатуру метода в интерфейсе.parse_pattern(&mut self) -> Result<ast::Pattern, ParserError>: Парсит различные типы паттернов дляmatchвыражений.parse_range_pattern(&mut self, start_expr: ast::Expression) -> Result<ast::Pattern, ParserError>: Парсит диапазонные паттерны.parse_struct_pattern(&mut self, name: ast::Identifier) -> Result<ast::Pattern, ParserError>: Парсит структурные паттерны.parse_match_arm(&mut self) -> Result<ast::MatchArm, ParserError>: Парсит одну ветвьmatchвыражения, включая паттерн, опциональный гард и тело.
use crate::lexer::Lexer;
use crate::parser::Parser;
use crate::ast::{Program, Statement, Expression, Identifier, IntegerLiteral, InfixExpression, BlockStatement, IfExpression};
use crate::token::{Token, TokenType};
let input = "let x = 5 + 10;".to_string();
let lexer = Lexer::new(input);
let mut parser = Parser::new(lexer);
let program = parser.parse_program().unwrap();
// Ожидаем один оператор Let
assert_eq!(program.statements.len(), 1);
if let Statement::Let(let_stmt) = &program.statements[0] {
assert_eq!(let_stmt.name.value, "x");
if let Expression::Infix(infix_exp) = &let_stmt.value {
if let Expression::IntegerLiteral(left_val) = &*infix_exp.left {
assert_eq!(left_val.value, 5);
}
assert_eq!(infix_exp.operator, "+");
if let Expression::IntegerLiteral(right_val) = &*infix_exp.right {
assert_eq!(right_val.value, 10);
}
}
}
let input_if = "if (x < y) { return x; } else { return y; }".to_string();
let lexer_if = Lexer::new(input_if);
let mut parser_if = Parser::new(lexer_if);
let program_if = parser_if.parse_program().unwrap();
if let Statement::Expression(expr_stmt) = &program_if.statements[0] {
if let Expression::If(if_expr) = &expr_stmt.expression {
assert_eq!(if_expr.condition.to_string(), "(x < y)");
assert_eq!(if_expr.consequence.statements.len(), 1);
assert!(if_expr.alternative.is_some());
}
}