Parses a boolean operation expression. Note that the boolean `not` operator is parsed as a unary expression and not as a boolean expression. # Panics If the parser isn't positioned at a `or` or `and` token. See:
(
&mut self,
lhs: Expr,
start: TextSize,
op: BoolOp,
context: ExpressionContext,
)
| 1242 | /// |
| 1243 | /// See: <https://docs.python.org/3/reference/expressions.html#boolean-operations> |
| 1244 | fn parse_boolean_expression( |
| 1245 | &mut self, |
| 1246 | lhs: Expr, |
| 1247 | start: TextSize, |
| 1248 | op: BoolOp, |
| 1249 | context: ExpressionContext, |
| 1250 | ) -> ast::ExprBoolOp { |
| 1251 | self.bump(TokenKind::from(op)); |
| 1252 | |
| 1253 | let values_snapshot = self.expr_scratch.snapshot(); |
| 1254 | self.expr_scratch.push(lhs); |
| 1255 | let mut progress = ParserProgress::default(); |
| 1256 | |
| 1257 | // Keep adding the expression to `values` until we see a different |
| 1258 | // token than `operator_token`. |
| 1259 | loop { |
| 1260 | progress.assert_progressing(self); |
| 1261 | |
| 1262 | let parsed_expr = |
| 1263 | self.parse_binary_expression_or_higher(OperatorPrecedence::from(op), context); |
| 1264 | self.expr_scratch.push(parsed_expr.expr); |
| 1265 | |
| 1266 | if !self.eat(TokenKind::from(op)) { |
| 1267 | break; |
| 1268 | } |
| 1269 | } |
| 1270 | |
| 1271 | ast::ExprBoolOp { |
| 1272 | values: self.expr_scratch.take(values_snapshot), |
| 1273 | op, |
| 1274 | range: self.node_range(start), |
| 1275 | node_index: AtomicNodeIndex::NONE, |
| 1276 | } |
| 1277 | } |
| 1278 | |
| 1279 | /// Bump the appropriate token(s) for the given comparison operator. |
| 1280 | fn bump_cmp_op(&mut self, op: CmpOp) { |
no test coverage detected