以下是记录在案的contents:
starred_list ::= starred_item ( "," starred_item )* [","]
starred_expression ::= expression | ( starred_item "," )* [starred_item]
我不能说出它们之间的区别,它们不是等同的规则吗?
答案 0 :(得分:1)
引用的语法与实际语法不同(尽管人们希望两者具有相同的效果);您可以在参考手册的Chapter 10中看到实际用于生成CPython解析器的语法。这两个语法在非终端名称上没有区别,因此,哪些源代码产生与引用的规则相对应并不完全明显。
从广义上讲,引用的两个作品之间的差异是语义的,而不是句法的;两部作品都产生完全相同的有效句子。语义差异是处理单个unstarred表达式而没有尾随逗号;第一种选择:
starred_expression ::= expression | ( starred_item "," )* [starred_item]
还可以使用expresion
的第一个备选方案,通过匹配( starred_item "," )
的零重复,然后匹配单个starred_item
,从第二个备选方案派生starred_item
。然而,明确冗余的交替被指定,因为两个替代方案具有不同的语义:
( x )
是一个简单的括号表达式,而
( x , )
是一个单元素元组。只有当表达式列表被括号括起时才需要这种区别;如果它被括号或大括号包围,则两种情况之间没有语义区别:[ x ]
在语义上与[ x , ]
相同,与{ x }
和{ x , }
类似。这反映在语法上;在生产中可以产生带括号的表达式或元组,使用starred_expression
:
parenth_form ::= "(" [starred_expression] ")"
在其他文字语法中,我们看到starred_list
,其中不包含冗余备选:
list_display ::= "[" [starred_list | comprehension] "]"
set_display ::= "{" (starred_list | comprehension) "}"