expr_solver/parser.rs
1use std::vec;
2
3use crate::ast::AST;
4use crate::lexer::Lexer;
5use crate::token::Token;
6
7// Top level parser.
8// parses linear array of tokens into AST.
9pub struct Parser<'a> {
10 lexer: &'a mut Lexer,
11}
12
13impl<'a> Parser<'a> {
14 // constructor for parser.
15 pub fn new(lexer: &'a mut Lexer) -> Self {
16 log::debug!("[expr-solver] Creating new parser instance.");
17 Self { lexer }
18 }
19
20 // public parse method.
21 pub fn parse(&mut self) -> Result<AST, String> {
22 log::debug!("[expr-solver] starting parsing.");
23 // we start with binding power of 0.
24 match self.expr(0) {
25 Ok(ast) => {
26 log::debug!("Parsed to ast:\n{}", ast);
27 Ok(ast)
28 }
29 Err(e) => {
30 log::debug!("Failed to parse AST.");
31 Err(e)
32 }
33 }
34 }
35
36 /// Parses an expression using Operator-Precedence parse (Pratt Parsing)
37 /// ref : https://en.wikipedia.org/wiki/Operator-precedence_parser
38 /// # Arguments
39 /// * min_binding_power - minimum binding power till recursivel parse the expression.
40 /// # Returns
41 /// * AST - ast of the expression.
42 fn expr(&mut self, min_binding_power: u8) -> Result<AST, String> {
43 // Parsing left hand side of the expression.
44 let mut left_hand_side = match self.lexer.next_token() {
45 // if the token is a number we simply create a node out of it.
46 Token::Number(f) => AST::Node(Token::Number(f)),
47
48 // if we reached the end we panic.
49 Token::Eof => return Err("Unexpected token : EOF".to_string()),
50
51 // if grouping, the AST can be treated as primary expression.
52 Token::LeftParen => {
53 let lhs = match self.expr(0) {
54 Ok(lhs) => lhs,
55 Err(e) => return Err(e),
56 };
57
58 if !matches!(self.lexer.next_token(), Token::RightParen) {
59 return Err("Expected ')' after expression.".to_string());
60 }
61
62 lhs
63 }
64
65 // if its a operator, then it means the operator is a unary.
66 operator => {
67 // we get the right binding power of the unary operator.
68 let ((), right_binding_power) = Parser::prefix_binding_power(operator);
69
70 // then recursively parse it.
71 match self.expr(right_binding_power) {
72 // save if its safe.
73 Ok(right_hand_side) => AST::Con(operator, vec![right_hand_side]),
74 // return if err.
75 Err(err) => return Err(err),
76 }
77 }
78 };
79
80 loop {
81 // Operator: Infix operator.
82 let operator = match self.lexer.peek() {
83 // shouldn't be a number, obviously.
84 Token::Number(n) => return Err(format!("Expected operator recieved number : {n}")),
85
86 // also shouldn't end.
87 Token::Eof => break,
88
89 // take the operator.
90 op => op,
91 };
92
93 // get the left binding power of the postfix operator.
94 if let Some((left_bp, ())) = Parser::postfix_binding_power(operator) {
95 // we break the loop when precendence of the current left binding
96 // power of the postfix operator is less than minimum binding power.
97 if left_bp < min_binding_power {
98 break;
99 }
100 self.lexer.next_token();
101
102 left_hand_side = AST::Con(operator, vec![left_hand_side]);
103
104 // we need to skip the current iteration.
105 continue;
106 }
107
108 // get the left binding power and right binding power of this infix operator.
109 if let Some((left_bp, right_bp)) = Parser::infix_binding_power(operator) {
110 // ends recursion when the minimum binding power for this
111 // expr function call is less then left binding power of the current operator.
112 if left_bp < min_binding_power {
113 break;
114 }
115
116 // consume operator token.
117 self.lexer.next_token();
118
119 // recurisvely call expr to parse right hand side of the expression.
120 match self.expr(right_bp) {
121 Ok(right_hand_side) => {
122 // create ast.
123 left_hand_side = AST::Con(operator, vec![left_hand_side, right_hand_side]);
124 }
125 Err(err) => return Err(err),
126 }
127
128 continue;
129 }
130
131 // break the loop if none of the above cases are met.
132 break;
133 }
134
135 // return the created AST.
136 Ok(left_hand_side)
137 }
138
139 /// Gets the infix binding power of a operator.
140 /// # Arguments
141 /// * token - the operator token.
142 /// # Returns
143 /// * (left, right) - left and right infix binding power of the operator.
144 fn infix_binding_power(token: Token) -> Option<(u8, u8)> {
145 let power = match token {
146 Token::Plus => (1, 2),
147 Token::Minus => (1, 2),
148 Token::Star => (3, 4),
149 Token::Slash => (3, 4),
150
151 // basically unreachable.
152 _ => return None,
153 };
154
155 Some(power)
156 }
157
158 /// Gets the postfix binding power of a operator.
159 /// # Arguments
160 /// * token - the operator token.
161 /// # Returns
162 /// * (left, ())) - left postfix binding power of the operator.
163 fn postfix_binding_power(token: Token) -> Option<(u8, ())> {
164 let power = match token {
165 Token::Bang => (6, ()),
166
167 // basically unreachable.
168 _ => return None,
169 };
170
171 Some(power)
172 }
173
174 /// Gets the prefix binding power of a unary operators.
175 /// # Arguments
176 /// * token - the operator token.
177 /// # Returns
178 /// * ((), right) - right prefix binding power of the operator.
179 fn prefix_binding_power(token: Token) -> ((), u8) {
180 match token {
181 Token::Minus | Token::Plus => ((), 5),
182
183 // basically unreachable.
184 t => panic!("Cannot get infix binding power of {t}"),
185 }
186 }
187}