关于Python赋值语句BNF规则与简单赋值语句匹配逻辑的疑问
嘿,我完全懂你对着BNF挠头的感觉!当初我第一次啃Python的语法规则时,也被这些层层嵌套的规则绕晕过,尤其是碰到a=9这种超基础的语句,反而不知道怎么对应上去了。咱们一步一步拆解,把这个匹配过程理清楚:
首先先把你提到的相关BNF规则列出来(方便对照):
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression) target_list ::= target ("," target)* [","] target ::= identifier | "(" [target_list] ")" | "[" [target_list] "]" | attributeref | subscription | slicing | "*" target starred_expression ::= expression | (starred_item ",")* [starred_item] starred_item ::= assignment_expression | "*" or_expr yield_atom ::= "(" yield_expression ")" yield_expression ::= "yield" [expression_list | "from" expression]
接下来咱们逐个对应a=9的每一部分:
1. 匹配最顶层的assignment_stmt
a=9是单次赋值,所以对应(target_list "=")+里的单次target_list "="结构,也就是a =这部分;右边的9显然不是yield_expression(没有yield关键字),所以它必然属于starred_expression。
2. 匹配左边的target_list
target_list的规则是target ("," target)* [","],这里我们只有一个目标a,所以直接匹配target这单个元素的情况,不需要逗号分隔的多个target,也不用 trailing comma。
3. 匹配target
a是一个标准的标识符(变量名),正好对应target规则里的第一个选项identifier,完美契合,这部分没有任何问题。
4. 匹配右边的starred_expression
这是最容易困惑的点:9怎么就属于starred_expression了?
看规则:starred_expression的第一个选项就是expression——也就是说,任何合法的Python表达式,都可以直接作为starred_expression的一种情况。
那9是不是合法的表达式?当然是!顺着语法递归下去:expression → or_expr → and_expr → shift_expr → arith_expr → term → factor → primary → atom,而atom的完整规则(官方文档里)明确包含数字字面量,比如像9这样的整数。所以9是一个合法的expression,自然就符合starred_expression的要求了。
简单来说,starred_expression这个名字容易误导人,以为必须带*,但实际上它的规则里允许普通表达式直接匹配,这就是为什么9能适配进去的核心原因。
备注:内容来源于stack exchange,提问作者novice

