The cited grammar is not identical to the actual grammar (although one hopes that the two have identical effect); you can see the grammar actually used to generate the CPython parser in Chapter 10 of the reference manual. The two grammars do not differ solely in the names of non-terminals, so it is not entirely obvious which source code productions correspond to the quoted rules.
Broadly speaking, the difference between the two productions quoted is semantic, not syntactic; both productions yield exactly the same set of valid sentences. The semantic difference is the handling of a single unstarred expression with no trailing comma; the first alternative of:
starred_expression ::= expression | ( starred_item "," )* [starred_item]
It would also be possible to derive expresion
from the second alternative, by matching zero repetitions of ( starred_item "," )
and then a single starred_item
, using the first alternative of starred_item
. However, the apparently redundant alternation is specified because the two alternatives have different semantics:
( x )
is a simple parenthesized expression, whereas
( x , )
is a one-element tuple. This distinction is only needed if the expression list is surrounded by parentheses; if it is surrounded by brackets or braces, there is no semantic distinction between the two cases: [ x ]
is semantically identical to [ x , ]
and similarly with { x }
and { x , }
. This is reflected in the grammar; in the production which could produce either a parenthesized expression or a tuple, starred_expression
is used:
parenth_form ::= "(" [starred_expression] ")"
In the other literal syntaxes, we see starred_list
, which does not include the redundant alternative:
list_display ::= "[" [starred_list | comprehension] "]"
set_display ::= "{" (starred_list | comprehension) "}"