mirror of
https://github.com/python/cpython.git
synced 2025-10-21 14:12:27 +00:00
PEP 308 implementation, including minor refdocs and some testcases. It
breaks the parser module, because it adds the if/else construct as well as two new grammar rules for backward compatibility. If no one else fixes parsermodule, I guess I'll go ahead and fix it later this week. The TeX code was checked with texcheck.py, but not rendered. There is actually a slight incompatibility: >>> (x for x in lambda:0) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: iteration over non-sequence changes into >>> (x for x in lambda: 0) File "<stdin>", line 1 (x for x in lambda: 0) ^ SyntaxError: invalid syntax Since there's no way the former version can be useful, it's probably a bugfix ;)
This commit is contained in:
parent
d3a5f53a27
commit
dca3b9c797
11 changed files with 878 additions and 642 deletions
40
Python/ast.c
40
Python/ast.c
|
@ -847,6 +847,25 @@ ast_for_lambdef(struct compiling *c, const node *n)
|
|||
return Lambda(args, expression, LINENO(n), c->c_arena);
|
||||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_ifexpr(struct compiling *c, const node *n)
|
||||
{
|
||||
/* test: or_test 'if' or_test 'else' test */
|
||||
expr_ty expression, body, orelse;
|
||||
|
||||
assert(NCH(n) >= 3);
|
||||
body = ast_for_expr(c, CHILD(n, 0));
|
||||
if (!body)
|
||||
return NULL;
|
||||
expression = ast_for_expr(c, CHILD(n, 2));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
orelse = ast_for_expr(c, CHILD(n, 4));
|
||||
if (!orelse)
|
||||
return NULL;
|
||||
return IfExp(expression, body, orelse, LINENO(n), c->c_arena);
|
||||
}
|
||||
|
||||
/* Count the number of 'for' loop in a list comprehension.
|
||||
|
||||
Helper for ast_for_listcomp().
|
||||
|
@ -1456,7 +1475,8 @@ static expr_ty
|
|||
ast_for_expr(struct compiling *c, const node *n)
|
||||
{
|
||||
/* handle the full range of simple expressions
|
||||
test: and_test ('or' and_test)* | lambdef
|
||||
test: or_test ['if' or_test 'else' test] | lambdef
|
||||
or_test: and_test ('or' and_test)*
|
||||
and_test: not_test ('and' not_test)*
|
||||
not_test: 'not' not_test | comparison
|
||||
comparison: expr (comp_op expr)*
|
||||
|
@ -1468,6 +1488,15 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
term: factor (('*'|'/'|'%'|'//') factor)*
|
||||
factor: ('+'|'-'|'~') factor | power
|
||||
power: atom trailer* ('**' factor)*
|
||||
|
||||
As well as modified versions that exist for backward compatibility,
|
||||
to explicitly allow:
|
||||
[ x for x in lambda: 0, lambda: 1 ]
|
||||
(which would be ambiguous without these extra rules)
|
||||
|
||||
old_test: or_test | old_lambdef
|
||||
old_lambdef: 'lambda' [vararglist] ':' old_test
|
||||
|
||||
*/
|
||||
|
||||
asdl_seq *seq;
|
||||
|
@ -1476,9 +1505,14 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
loop:
|
||||
switch (TYPE(n)) {
|
||||
case test:
|
||||
if (TYPE(CHILD(n, 0)) == lambdef)
|
||||
case old_test:
|
||||
if (TYPE(CHILD(n, 0)) == lambdef ||
|
||||
TYPE(CHILD(n, 0)) == old_lambdef)
|
||||
return ast_for_lambdef(c, CHILD(n, 0));
|
||||
/* Fall through to and_test */
|
||||
else if (NCH(n) > 1)
|
||||
return ast_for_ifexpr(c, n);
|
||||
/* Fallthrough */
|
||||
case or_test:
|
||||
case and_test:
|
||||
if (NCH(n) == 1) {
|
||||
n = CHILD(n, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue