Merge pull request #4356 from andersk/with-tuple-named

Fix parsing of tuple with named expression as context manager
This commit is contained in:
Jeong YunWon 2022-12-26 16:02:17 +09:00 committed by GitHub
commit d7986317c1
2 changed files with 141 additions and 116 deletions

View file

@ -164,6 +164,11 @@ TestOrStarExpr: ast::Expr = {
StarExpr,
};
NamedOrStarExpr: ast::Expr = {
NamedExpression,
StarExpr,
};
TestOrStarNamedExpr: ast::Expr = {
NamedExpressionTest,
StarExpr,
@ -518,7 +523,7 @@ WithItems: Vec<ast::Withitem> = {
#[inline]
WithItemsNoAs: Vec<ast::Withitem> = {
<OneOrMore<NamedExpressionTest>> => {
<OneOrMore<Test<"all">>> => {
<>.into_iter().map(|context_expr| ast::Withitem { context_expr, optional_vars: None }).collect()
},
}
@ -746,8 +751,12 @@ Test<Goal>: ast::Expr = {
};
NamedExpressionTest: ast::Expr = {
<location:@L> <left: (Identifier ":=")?> <right:Test<"all">> <end_location:@R> => {
if let Some(l) = left {
NamedExpression,
Test<"all">,
}
NamedExpression: ast::Expr = {
<location:@L> <id:Identifier> ":=" <value:Test<"all">> <end_location:@R> => {
ast::Expr {
location,
end_location: Some(end_location),
@ -756,16 +765,13 @@ NamedExpressionTest: ast::Expr = {
target: Box::new(ast::Expr::new(
location,
end_location,
ast::ExprKind::Name { id: l.0, ctx: ast::ExprContext::Store },
ast::ExprKind::Name { id, ctx: ast::ExprContext::Store },
)),
value: Box::new(right),
value: Box::new(value),
}
}
} else {
right
}
}
}
},
};
LambdaDef: ast::Expr = {
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> => {
@ -1066,7 +1072,7 @@ Atom<Goal>: ast::Expr = {
node: ast::ExprKind::ListComp { elt: Box::new(elt), generators }
}
},
<location:@L> "(" <elts:OneOrMore<NamedExpressionTest>> <trailing_comma:","?> ")" <end_location:@R> if Goal != "no-withitems" => {
<location:@L> "(" <elts:OneOrMore<Test<"all">>> <trailing_comma:","?> ")" <end_location:@R> if Goal != "no-withitems" => {
if elts.len() == 1 && trailing_comma.is_none() {
elts.into_iter().next().unwrap()
} else {
@ -1077,19 +1083,23 @@ Atom<Goal>: ast::Expr = {
)
}
},
<location:@L> "(" <left:(<OneOrMore<NamedExpressionTest>> ",")?> <mid:StarExpr> <right:("," <TestOrStarNamedExpr>)*> <trailing_comma:","?> ")" <end_location:@R> =>? {
<location:@L> "(" <left:(<OneOrMore<Test<"all">>> ",")?> <mid:NamedOrStarExpr> <right:("," <TestOrStarNamedExpr>)*> <trailing_comma:","?> ")" <end_location:@R> =>? {
if left.is_none() && right.is_empty() && trailing_comma.is_none() {
if matches!(mid.node, ast::ExprKind::Starred { .. }) {
Err(LexicalError{
error: LexicalErrorType::OtherError("cannot use starred expression here".to_string()),
location: mid.location,
})?
}
Ok(mid)
} else {
let elts = left.into_iter().flatten().chain([mid]).chain(right).collect();
Ok(ast::Expr::new(
location,
end_location,
ast::ExprKind::Tuple { elts, ctx: ast::ExprContext::Load },
))
}
},
<location:@L> "(" ")" <end_location:@R> => ast::Expr::new(
location,

View file

@ -1790,6 +1790,20 @@ expression: "parse_program(source, \"<test>\").unwrap()"
items: [
Withitem {
context_expr: Located {
location: Location {
row: 21,
column: 5,
},
end_location: Some(
Location {
row: 21,
column: 21,
},
),
custom: (),
node: Tuple {
elts: [
Located {
location: Location {
row: 21,
column: 6,
@ -1840,10 +1854,7 @@ expression: "parse_program(source, \"<test>\").unwrap()"
},
},
},
optional_vars: None,
},
Withitem {
context_expr: Located {
Located {
location: Location {
row: 21,
column: 14,
@ -1894,6 +1905,10 @@ expression: "parse_program(source, \"<test>\").unwrap()"
},
},
},
],
ctx: Load,
},
},
optional_vars: None,
},
],