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, StarExpr,
}; };
NamedOrStarExpr: ast::Expr = {
NamedExpression,
StarExpr,
};
TestOrStarNamedExpr: ast::Expr = { TestOrStarNamedExpr: ast::Expr = {
NamedExpressionTest, NamedExpressionTest,
StarExpr, StarExpr,
@ -518,7 +523,7 @@ WithItems: Vec<ast::Withitem> = {
#[inline] #[inline]
WithItemsNoAs: Vec<ast::Withitem> = { WithItemsNoAs: Vec<ast::Withitem> = {
<OneOrMore<NamedExpressionTest>> => { <OneOrMore<Test<"all">>> => {
<>.into_iter().map(|context_expr| ast::Withitem { context_expr, optional_vars: None }).collect() <>.into_iter().map(|context_expr| ast::Withitem { context_expr, optional_vars: None }).collect()
}, },
} }
@ -746,27 +751,28 @@ Test<Goal>: ast::Expr = {
}; };
NamedExpressionTest: ast::Expr = { NamedExpressionTest: ast::Expr = {
<location:@L> <left: (Identifier ":=")?> <right:Test<"all">> <end_location:@R> => { NamedExpression,
if let Some(l) = left { Test<"all">,
ast::Expr {
location,
end_location: Some(end_location),
custom: (),
node: ast::ExprKind::NamedExpr {
target: Box::new(ast::Expr::new(
location,
end_location,
ast::ExprKind::Name { id: l.0, ctx: ast::ExprContext::Store },
)),
value: Box::new(right),
}
}
} else {
right
}
}
} }
NamedExpression: ast::Expr = {
<location:@L> <id:Identifier> ":=" <value:Test<"all">> <end_location:@R> => {
ast::Expr {
location,
end_location: Some(end_location),
custom: (),
node: ast::ExprKind::NamedExpr {
target: Box::new(ast::Expr::new(
location,
end_location,
ast::ExprKind::Name { id, ctx: ast::ExprContext::Store },
)),
value: Box::new(value),
}
}
},
};
LambdaDef: ast::Expr = { LambdaDef: ast::Expr = {
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> => { <location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> => {
let p = p.unwrap_or_else(|| { let p = p.unwrap_or_else(|| {
@ -1066,7 +1072,7 @@ Atom<Goal>: ast::Expr = {
node: ast::ExprKind::ListComp { elt: Box::new(elt), generators } 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() { if elts.len() == 1 && trailing_comma.is_none() {
elts.into_iter().next().unwrap() elts.into_iter().next().unwrap()
} else { } 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 left.is_none() && right.is_empty() && trailing_comma.is_none() {
Err(LexicalError{ if matches!(mid.node, ast::ExprKind::Starred { .. }) {
error: LexicalErrorType::OtherError("cannot use starred expression here".to_string()), Err(LexicalError{
location: mid.location, 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 },
))
} }
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:@L> "(" ")" <end_location:@R> => ast::Expr::new(
location, location,

View file

@ -1792,106 +1792,121 @@ expression: "parse_program(source, \"<test>\").unwrap()"
context_expr: Located { context_expr: Located {
location: Location { location: Location {
row: 21, row: 21,
column: 6, column: 5,
}, },
end_location: Some( end_location: Some(
Location { Location {
row: 21, row: 21,
column: 12, column: 21,
}, },
), ),
custom: (), custom: (),
node: NamedExpr { node: Tuple {
target: Located { elts: [
location: Location { Located {
row: 21, location: Location {
column: 6,
},
end_location: Some(
Location {
row: 21, row: 21,
column: 12, column: 6,
}, },
), end_location: Some(
custom: (), Location {
node: Name { row: 21,
id: "a", column: 12,
ctx: Store, },
},
},
value: Located {
location: Location {
row: 21,
column: 11,
},
end_location: Some(
Location {
row: 21,
column: 12,
},
),
custom: (),
node: Constant {
value: Int(
0,
), ),
kind: None, custom: (),
}, node: NamedExpr {
}, target: Located {
}, location: Location {
}, row: 21,
optional_vars: None, column: 6,
}, },
Withitem { end_location: Some(
context_expr: Located { Location {
location: Location { row: 21,
row: 21, column: 12,
column: 14, },
}, ),
end_location: Some( custom: (),
Location { node: Name {
row: 21, id: "a",
column: 20, ctx: Store,
}, },
), },
custom: (), value: Located {
node: NamedExpr { location: Location {
target: Located { row: 21,
location: Location { column: 11,
row: 21, },
column: 14, end_location: Some(
}, Location {
end_location: Some( row: 21,
Location { column: 12,
row: 21, },
column: 20, ),
custom: (),
node: Constant {
value: Int(
0,
),
kind: None,
},
},
}, },
),
custom: (),
node: Name {
id: "b",
ctx: Store,
}, },
}, Located {
value: Located { location: Location {
location: Location {
row: 21,
column: 19,
},
end_location: Some(
Location {
row: 21, row: 21,
column: 20, column: 14,
}, },
), end_location: Some(
custom: (), Location {
node: Constant { row: 21,
value: Int( column: 20,
1, },
), ),
kind: None, custom: (),
node: NamedExpr {
target: Located {
location: Location {
row: 21,
column: 14,
},
end_location: Some(
Location {
row: 21,
column: 20,
},
),
custom: (),
node: Name {
id: "b",
ctx: Store,
},
},
value: Located {
location: Location {
row: 21,
column: 19,
},
end_location: Some(
Location {
row: 21,
column: 20,
},
),
custom: (),
node: Constant {
value: Int(
1,
),
kind: None,
},
},
},
}, },
}, ],
ctx: Load,
}, },
}, },
optional_vars: None, optional_vars: None,