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,
)
| 1164 | /// |
| 1165 | /// See: <https://docs.python.org/3/reference/expressions.html#boolean-operations> |
| 1166 | fn parse_boolean_expression( |
| 1167 | &mut self, |
| 1168 | lhs: Expr, |
| 1169 | start: TextSize, |
| 1170 | op: BoolOp, |
| 1171 | context: ExpressionContext, |
| 1172 | ) -> ast::ExprBoolOp { |
| 1173 | self.bump(TokenKind::from(op)); |
| 1174 | |
| 1175 | let values_snapshot = self.expr_scratch.snapshot(); |
| 1176 | self.expr_scratch.push(lhs); |
| 1177 | let mut progress = ParserProgress::default(); |
| 1178 | |
| 1179 | // Keep adding the expression to `values` until we see a different |
| 1180 | // token than `operator_token`. |
| 1181 | loop { |
| 1182 | progress.assert_progressing(self); |
| 1183 | |
| 1184 | let parsed_expr = |
| 1185 | self.parse_binary_expression_or_higher(OperatorPrecedence::from(op), context); |
| 1186 | self.expr_scratch.push(parsed_expr.expr); |
| 1187 | |
| 1188 | if !self.eat(TokenKind::from(op)) { |
| 1189 | break; |
| 1190 | } |
| 1191 | } |
| 1192 | |
| 1193 | ast::ExprBoolOp { |
| 1194 | values: self.expr_scratch.take(values_snapshot), |
| 1195 | op, |
| 1196 | range: self.node_range(start), |
| 1197 | node_index: AtomicNodeIndex::NONE, |
| 1198 | } |
| 1199 | } |
| 1200 | |
| 1201 | /// Bump the appropriate token(s) for the given comparison operator. |
| 1202 | fn bump_cmp_op(&mut self, op: CmpOp) { |
no test coverage detected