Parse an expression with Pratt precedence.
(&mut self, min_prec: u8)
| 61 | |
| 62 | /// Parse an expression with Pratt precedence. |
| 63 | fn parse_expr(&mut self, min_prec: u8) -> Result<Expr, PromqlError> { |
| 64 | let mut lhs = self.parse_unary()?; |
| 65 | |
| 66 | while let Some(op) = self.peek_binop() { |
| 67 | if op.precedence() < min_prec { |
| 68 | break; |
| 69 | } |
| 70 | self.advance(); |
| 71 | |
| 72 | let return_bool = op.is_comparison() && self.try_keyword("bool"); |
| 73 | let matching = if op.is_set_op() { |
| 74 | self.try_parse_set_matching()? |
| 75 | } else { |
| 76 | self.try_parse_vector_matching()? |
| 77 | }; |
| 78 | |
| 79 | let next_prec = if matches!(op, BinOp::Pow) { |
| 80 | op.precedence() // right-associative |
| 81 | } else { |
| 82 | op.precedence() + 1 |
| 83 | }; |
| 84 | let rhs = self.parse_expr(next_prec)?; |
| 85 | |
| 86 | lhs = Expr::BinaryOp { |
| 87 | op, |
| 88 | lhs: Box::new(lhs), |
| 89 | rhs: Box::new(rhs), |
| 90 | return_bool, |
| 91 | matching, |
| 92 | }; |
| 93 | } |
| 94 | |
| 95 | Ok(lhs) |
| 96 | } |
| 97 | |
| 98 | fn parse_unary(&mut self) -> Result<Expr, PromqlError> { |
| 99 | if matches!(self.peek(), Token::Sub) { |
no test coverage detected