r2rust_core/parser.rs
1/// Parser module for constructing an Abstract Syntax Tree (AST) from tokens.
2///
3/// This module converts a sequence of tokens, generated by the lexer,
4/// into structured statements and expressions that can be evaluated.
5
6use crate::ast::{Expr, Statement};
7use crate::lexer::Token;
8
9/// Parses a sequence of tokens into a statement.
10///
11/// # Arguments
12/// * `tokens` - A slice of tokens to be parsed.
13///
14/// # Returns
15/// A `Statement` representing the parsed tokens, or an error if the parsing fails.
16///
17/// # Errors
18/// This function returns an error string if the token sequence is invalid.
19///
20/// # Examples
21/// ```
22/// use r2rust_core::lexer::tokenize;
23/// use r2rust_core::parser::parse;
24///
25/// let tokens = tokenize("x <- 10 + 32");
26/// let statement = parse(&tokens).unwrap();
27/// ```
28pub fn parse(tokens: &[Token]) -> Result<Statement, String> {
29 let mut iter = tokens.iter().peekable();
30
31 // Parse an assignment statement (e.g., "x <- expression")
32 if let Some(Token::Identifier(var)) = iter.next() {
33 if let Some(Token::Assign) = iter.next() {
34 let expr = parse_expr(&mut iter)?;
35 return Ok(Statement::Assign(var.clone(), expr));
36 } else {
37 return Err("Expected '<-' after variable name".to_string());
38 }
39 }
40
41 // Parse a standalone expression
42 let expr = parse_expr(&mut iter)?;
43 Ok(Statement::Expr(expr))
44}
45
46/// Parses an expression from a sequence of tokens.
47///
48/// This function handles operator precedence and ensures the correct
49/// construction of the expression tree.
50///
51/// # Arguments
52/// * `iter` - A mutable peekable iterator over tokens.
53///
54/// # Returns
55/// An `Expr` representing the parsed expression, or an error if the parsing fails.
56fn parse_expr(iter: &mut std::iter::Peekable<std::slice::Iter<Token>>) -> Result<Expr, String> {
57 let mut left = parse_primary(iter)?;
58
59 // Handle binary operators like `+` and `-`
60 while let Some(op) = iter.peek() {
61 left = match op {
62 Token::Plus => {
63 iter.next(); // Consume the operator
64 Expr::Add(Box::new(left), Box::new(parse_primary(iter)?))
65 }
66 Token::Minus => {
67 iter.next(); // Consume the operator
68 Expr::Sub(Box::new(left), Box::new(parse_primary(iter)?))
69 }
70 _ => break, // Exit the loop if no operator is found
71 };
72 }
73
74 Ok(left)
75}
76
77/// Parses a primary expression (e.g., a number or a variable).
78///
79/// # Arguments
80/// * `iter` - A mutable peekable iterator over tokens.
81///
82/// # Returns
83/// An `Expr` representing the parsed primary expression, or an error if the parsing fails.
84fn parse_primary(iter: &mut std::iter::Peekable<std::slice::Iter<Token>>) -> Result<Expr, String> {
85 match iter.next() {
86 Some(Token::Number(n)) => Ok(Expr::Number(*n)),
87 Some(Token::Identifier(var)) => Ok(Expr::Variable(var.clone())),
88 _ => Err("Unexpected token".to_string()),
89 }
90}