[Python-Dev] small Grammar questions
Brett Cannon
brett at python.org
Wed Feb 20 00:29:23 CET 2008
On Feb 19, 2008 1:38 PM, Andrew Dalke <dalke at dalkescientific.com> wrote:
> I'm finishing up a PLY lexer and parser for the current CVS version of
> the Python grammar. As part of it I've been testing a lot of dark
> corners in the grammar definition and implementation. Python 2.5 has
> some small and rare problems which I'm pleased to note have been
> pretty much fixed in Python 2.6.
>
> I have two questions about the grammar definition. Here's a
> difference between 2.5 and 2.6.
>
> % cat x.py
> c = "This is 'c'"
> def spam((a) = c):
> print a
> spam()
>
> % python2.5 x.py
> This is 'c'
> % python2.6 x.py
> File "x.py", line 2
> def spam((a) = c):
> SyntaxError: non-default argument follows default argument
>
>
> I don't understand why that's changed. This shouldn't be a
> SyntaxError and there is no non-default argument following the default
> argument.
>
The error might be odd, but I don't see why that should be allowed
syntax. Having a parameter surrounded by a parentheses like that makes
no sense in a context of a place where arbitrary expressions are not
allowed.
> Note that this is still valid
>
> >>> def spam((a,) = c):
> ... pass
> ...
>
> I think 2.6 is incorrect. According to the documentation at
> http://docs.python.org/ref/function.html
>
> defparameter ::= parameter ["=" expression]
> sublist ::= parameter ("," parameter)* [","]
> parameter ::= identifier | "(" sublist ")"
> funcname ::= identifier
Looking at Grammar/Grammar, the relevant rules are::
parameters: '(' [varargslist] ')'
varargslist: ((fpdef ['=' test] ',')*
('*' NAME [',' '**' NAME] | '**' NAME) |
fpdef ['=' test] (',' fpdef ['=' test])* [','])
fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']
>From what I can tell the grammar does not prevent it. But it is
possible that during AST creation or bytecode compilation a specific
check is made that is throwing the exception...
And checking Python.ast.c:672 seems to suggest it is something the AST
is doing. I don't have time to dig deeper, but if you tried ``svn
blame`` and found out when that line was added the log message give
some clues as to why this is occurring.
>
>
> Second question is about trailing commas in list comprehension. I
> don't understand why the commented out line is not allowed.
>
> [x for x in 1]
> #[x for x in 1,] # This isn't legal
> [x for x in 1,2]
> [x for x in 1,2,]
> [x for x in 1,2,3]
>
> The Grammar file says
>
> # Backward compatibility cruft to support:
> # [ x for x in lambda: True, lambda: False if x() ]
> # even while also allowing:
> # lambda x: 5 if x else 2
> # (But not a mix of the two)
> testlist_safe: old_test [(',' old_test)+ [',']]
>
> but if I change it to also allow
>
> testlist_safe : old_test ','
>
> then PLY still doesn't report any ambiguities in the grammar and I
> can't find an expression that exhibits a problem.
>
> Could someone here enlighten me?
>
Are you asking why the decision was made to make the expression
illegal, or why the grammar is flagging it is wrong?
-Brett
More information about the Python-Dev
mailing list