“starred_list”和“starred_expression”之间EBNF规则的区别是什么?

时间:2016-12-13 06:20:52

标签: python python-3.x syntax ebnf

以下是记录在案的contents

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

我不能说出它们之间的区别,它们不是等同的规则吗?

1 个答案:

答案 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) "}"