die_sir/parsedie/
parser.rs

1use std::fmt;
2
3use super::{tokens::{Token, OperPrec}, lexer::{Lexer, LexerError}, ast::Node};
4
5pub struct Parser<'a> {
6    lexer: Lexer<'a>,
7    curr_token: Token,
8}
9
10impl<'a> Parser<'a> {
11    pub fn new(expr: &'a str) -> Result<Self, ParseError> {
12        let mut lexer = Lexer::new(expr);
13        let cur_token = match lexer.next() {
14            Some(Ok(token)) => token,
15            Some(Err(e)) => return Err(ParseError::from(e)),
16            None => return Err(ParseError::InvalidOperator(
17                "Invalid Character".into())),
18        };
19        Ok(Parser { lexer, curr_token: cur_token })
20    }
21
22    pub fn parse(&mut self) -> Result<Node, ParseError> {
23        let ast = self.generate_ast(OperPrec::DefaultZero);
24        match ast {
25            Ok(ast) => Ok(ast),
26            Err(e) => Err(e),
27        }
28    }
29
30    fn get_next_token(&mut self) -> Result<(), ParseError> {
31        let next_token = match self.lexer.next() {
32            Some(Ok(token)) => token,
33            Some(Err(e)) => return Err(ParseError::from(e)),
34            None => return Err(ParseError::InvalidOperator(
35                "Invalid character".into())),
36        };
37        self.curr_token = next_token;
38        Ok(())
39    }
40
41    fn check_paren(&mut self, expected: Token) -> Result<(), ParseError> {
42        if expected == self.curr_token {
43            self.get_next_token()?;
44            Ok(())
45        } else {
46            Err(ParseError::InvalidOperator(format!(
47                "Expected {:?}, got {:?}",
48                expected, self.curr_token
49            )))
50        }
51    }
52
53    fn parse_number (&mut self) -> Result<Node, ParseError> {
54        let token = self.curr_token.clone();
55        match token {
56            Token::Subtract => {
57                self.get_next_token()?;
58                let expr = self.generate_ast(OperPrec::Negative)?;
59                Ok(Node::Negative(Box::new(expr)))
60            }
61
62            Token::Num(i) => {
63                self.get_next_token()?;
64                Ok(Node::Number(i))
65            }
66
67            Token::LeftParen => {
68                self.get_next_token()?;
69                let expr = self.generate_ast(OperPrec::DefaultZero)?;
70                self.check_paren(Token::RightParen)?;
71                if self.curr_token == Token::LeftParen {
72                    let right = self.generate_ast(OperPrec::MulDiv)?;
73                    return Ok(Node::Multiply(Box::new(expr), Box::new(right)));
74                }
75                Ok(expr)
76            }
77            
78            _ => Err(ParseError::UnableToParse("Unable to parse".to_string())),
79        }
80    }
81
82    fn generate_ast(&mut self, oper_prec: OperPrec) -> Result<Node, ParseError> {
83        let mut left_expr = self.parse_number()?;
84
85        while oper_prec < self.curr_token.get_oper_prec() {
86            if self.curr_token == Token::EOF {
87                break;
88            }
89
90            let right_expr = self.convert_token_to_node(left_expr.clone())?;
91
92            left_expr = right_expr;
93        }
94        Ok(left_expr)
95    }
96
97    fn convert_token_to_node(&mut self, left_expr: Node) -> Result<Node, ParseError> {
98        match self.curr_token {
99            Token::Add => {
100                self.get_next_token()?;
101
102                let right_expr = self.generate_ast(OperPrec::AddSub)?;
103                Ok(Node::Add(Box::new(left_expr), Box::new(right_expr)))
104            }
105
106            Token::Subtract => {
107                self.get_next_token()?;
108
109                let right_expr = self.generate_ast(OperPrec::AddSub)?;
110
111                Ok(Node::Subtract(Box::new(left_expr), Box::new(right_expr)))
112            }
113
114            Token::Multiply => {
115                self.get_next_token()?;
116                let right_expr = self.generate_ast(OperPrec::MulDiv)?;
117
118                Ok(Node::Multiply(Box::new(left_expr), Box::new(right_expr)))
119            }
120
121            Token::Divide => {
122                self.get_next_token()?;
123
124                let right_expr = self.generate_ast(OperPrec::MulDiv)?;
125                
126                Ok(Node::Divide(Box::new(left_expr), Box::new(right_expr)))
127            }
128
129            Token::Caret => {
130                self.get_next_token()?;
131
132                let right_expr = self.generate_ast(OperPrec::Power)?;
133
134                Ok(Node::Caret(Box::new(left_expr), Box::new(right_expr)))
135            }
136
137            Token::Die => {
138                self.get_next_token()?;
139
140                let right_expr = self.generate_ast(OperPrec::DieRoll)?;
141
142                Ok(Node::Die(Box::new(left_expr), Box::new(right_expr)))
143            }
144
145            _ => Err(ParseError::InvalidOperator(format!("Please, enter a valid operator {:?}", self.curr_token))),
146        }
147    }
148}
149
150#[derive(Debug)]
151pub enum ParseError {
152    UnableToParse(String),
153    InvalidOperator(String),
154    NumberOverflow(String),
155}
156
157impl fmt::Display for ParseError {
158    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159        match self {
160            ParseError::UnableToParse(msg) => write!(f, "Unable to parse: {}", msg),
161            ParseError::InvalidOperator(msg) => write!(f, "Invalid operator: {}", msg),
162            ParseError::NumberOverflow(msg) => write!(f, "Number overflow: {}", msg),
163        }
164    }
165}
166
167impl From<LexerError> for ParseError {
168    fn from(error: LexerError) -> Self {
169        match error {
170            LexerError::ParseIntError(e) => ParseError::NumberOverflow(format!("Number is too large: {}", e)),
171            LexerError::InvalidCharacter(c) => ParseError::InvalidOperator(format!("Invalid character: {}", c)),
172        }
173    }
174}
175
176impl From<Box<dyn std::error::Error>> for ParseError {
177    fn from(error: Box<dyn std::error::Error>) -> Self {
178        ParseError::UnableToParse(error.to_string())
179    }
180}
181
182impl std::error::Error for ParseError {}