Pratt parsing implementation
(&mut self, precedence: Precedence)
| 2284 | |
| 2285 | // Pratt parsing implementation |
| 2286 | fn parse_precedence(&mut self, precedence: Precedence) -> Option<Expr<'gc>> { |
| 2287 | self.advance(); |
| 2288 | let prefix_rule = get_rule(self.previous.kind).prefix; |
| 2289 | let can_assign = precedence <= Precedence::Assignment; |
| 2290 | |
| 2291 | let expr = if let Some(prefix_fn) = prefix_rule { |
| 2292 | (prefix_fn)(self, can_assign) |
| 2293 | } else { |
| 2294 | self.error("Expect expression."); |
| 2295 | return None; |
| 2296 | }; |
| 2297 | |
| 2298 | self.previous_expr = expr; |
| 2299 | |
| 2300 | while precedence <= get_rule(self.current.kind).precedence { |
| 2301 | if self.stop_at_brace && self.current.kind == TokenType::OpenBrace { |
| 2302 | // If we're in a flow condition and see a '{', stop here |
| 2303 | // to let the statement parser handle the block |
| 2304 | break; |
| 2305 | } else if self.in_match_arm && self.current.kind == TokenType::If { |
| 2306 | // If we're in a match arm and see a 'if', stop here to |
| 2307 | // avoid conflict with match arm's if guard |
| 2308 | break; |
| 2309 | } |
| 2310 | |
| 2311 | self.advance(); |
| 2312 | // Do not reuse the previous rule since it may have changed. |
| 2313 | let infix_rule = get_rule(self.previous.kind).infix; |
| 2314 | if let Some(infix_fn) = infix_rule { |
| 2315 | let expr = (infix_fn)(self, can_assign)?; |
| 2316 | self.previous_expr = Some(expr); |
| 2317 | } |
| 2318 | } |
| 2319 | |
| 2320 | let expr = self.previous_expr.take()?; |
| 2321 | if can_assign && !matches!(expr, Expr::Variable { .. }) { |
| 2322 | match self.current.kind { |
| 2323 | TokenType::Equal |
| 2324 | | TokenType::PlusEqual |
| 2325 | | TokenType::MinusEqual |
| 2326 | | TokenType::StarEqual |
| 2327 | | TokenType::SlashEqual |
| 2328 | | TokenType::PercentEqual => { |
| 2329 | self.error_at_current("Invalid assignment target."); |
| 2330 | return None; |
| 2331 | } |
| 2332 | _ => {} |
| 2333 | } |
| 2334 | } |
| 2335 | Some(expr) |
| 2336 | } |
| 2337 | } |
| 2338 | |
| 2339 | // Precedence levels |
no test coverage detected