0

Here is the documented contents:

starred_list       ::=  starred_item ( "," starred_item )* [","]            
starred_expression ::=  expression | ( starred_item "," )* [starred_item]

I can't tell the difference between them, aren't they equivalent rules?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
wow yoo
  • 855
  • 8
  • 26

1 Answers1

1

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) "}"
rici
  • 234,347
  • 28
  • 237
  • 341
  • @wowyoo: As I said in my answer, they are syntactically identical but carry a semantic difference. That's what the first sentence of the second paragraph says. – rici Dec 13 '16 at 15:58
  • I should spare more time studying the documentation.Thanks for your help. – wow yoo Dec 13 '16 at 15:59
  • If the one can replace the other syntactically, why do we need two?One rule is enough. – wow yoo Dec 13 '16 at 16:11
  • Because parsing is not just to define what constitutes a valid program but also to explain how the parts relate to each other ("parse" and "part" have the same root). So the grammar needs to relate to the semantics. – rici Dec 13 '16 at 17:07
  • You mean the reason two rules coexist is to help make semantics more comprehensible,don't you? – wow yoo Dec 13 '16 at 17:16
  • 1
    No, I meant what I said. In general, making the semantics more comprehensible is a valuable side-effect of a grammar, but the primary purpose is to facilitate parsing *into a form suitable for semantic analysis.* Of course, the grammar you cite is essentially didactic, since it is not used directly to parse, so you could say that the reason any of the rules exist is to make the language more comprehensible. – rici Dec 13 '16 at 19:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/130574/discussion-between-wow-yoo-and-rici). – wow yoo Dec 14 '16 at 05:35