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}