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,
)
| 1244 | /// |
| 1245 | /// See: <https://docs.python.org/3/reference/expressions.html#boolean-operations> |
| 1246 | fn parse_boolean_expression( |
| 1247 | &mut self, |
| 1248 | lhs: Expr, |
| 1249 | start: TextSize, |
| 1250 | op: BoolOp, |
| 1251 | context: ExpressionContext, |
| 1252 | ) -> ast::ExprBoolOp { |
| 1253 | self.bump(TokenKind::from(op)); |
| 1254 | |
| 1255 | let mut values = Vec::with_capacity(2); |
| 1256 | values.push(lhs); |
| 1257 | let mut progress = ParserProgress::default(); |
| 1258 | |
| 1259 | // Keep adding the expression to `values` until we see a different |
| 1260 | // token than `operator_token`. |
| 1261 | loop { |
| 1262 | progress.assert_progressing(self); |
| 1263 | |
| 1264 | let parsed_expr = |
| 1265 | self.parse_binary_expression_or_higher(OperatorPrecedence::from(op), context); |
| 1266 | values.push(parsed_expr.expr); |
| 1267 | |
| 1268 | if !self.eat(TokenKind::from(op)) { |
| 1269 | break; |
| 1270 | } |
| 1271 | } |
| 1272 | |
| 1273 | values.shrink_to_fit(); |
| 1274 | |
| 1275 | ast::ExprBoolOp { |
| 1276 | values, |
| 1277 | op, |
| 1278 | range: self.node_range(start), |
| 1279 | node_index: AtomicNodeIndex::NONE, |
| 1280 | } |
| 1281 | } |
| 1282 | |
| 1283 | /// Bump the appropriate token(s) for the given comparison operator. |
| 1284 | fn bump_cmp_op(&mut self, op: CmpOp) { |
no test coverage detected