(
mut input: &str,
lhs: Expression,
min_precedence: Precedence,
)
| 140 | } |
| 141 | |
| 142 | pub fn parse_binary_expression_rest( |
| 143 | mut input: &str, |
| 144 | lhs: Expression, |
| 145 | min_precedence: Precedence, |
| 146 | ) -> IResult<&str, Expression> { |
| 147 | // Pratt Parsing Algorithm |
| 148 | // <https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html> |
| 149 | let mut lhs = lhs; |
| 150 | loop { |
| 151 | if let Ok((new_input, op)) = ws(parse_binary_expression_operator)(input) { |
| 152 | let left_precedence = op.precedence(); |
| 153 | |
| 154 | let stop = if left_precedence.is_right_associative() { |
| 155 | left_precedence < min_precedence |
| 156 | } else { |
| 157 | left_precedence <= min_precedence |
| 158 | }; |
| 159 | |
| 160 | if stop { |
| 161 | break; |
| 162 | } |
| 163 | |
| 164 | input = new_input; |
| 165 | |
| 166 | let (new_input, rhs) = parse_binary_expression_or_highier(input, left_precedence)?; |
| 167 | |
| 168 | lhs = Expression::BinaryExpression(Box::new(BinaryExpression { |
| 169 | left: lhs, |
| 170 | operator: op, |
| 171 | right: rhs, |
| 172 | })); |
| 173 | |
| 174 | input = new_input; |
| 175 | } else if let Ok((new_input, op)) = ws(parse_logical_operator)(input) { |
| 176 | let left_precedence = op.precedence(); |
| 177 | |
| 178 | let stop = if left_precedence.is_right_associative() { |
| 179 | left_precedence < min_precedence |
| 180 | } else { |
| 181 | left_precedence <= min_precedence |
| 182 | }; |
| 183 | |
| 184 | if stop { |
| 185 | break; |
| 186 | } |
| 187 | |
| 188 | input = new_input; |
| 189 | |
| 190 | let (new_input, rhs) = parse_binary_expression_or_highier(input, left_precedence)?; |
| 191 | |
| 192 | lhs = Expression::LogicalExpression(Box::new(LogicalExpression { |
| 193 | left: lhs, |
| 194 | operator: op, |
| 195 | right: rhs, |
| 196 | })); |
| 197 | |
| 198 | input = new_input; |
| 199 | } else { |
no test coverage detected