为什么在语法上无效的加法之后是逻辑不?

Why is logical not after an addition syntactically invalid?

今天,我注意到 not True + 5 在语法上是有效的,但 5 + not True 不是。 语法错误指向 not 的第一个字符,就好像这里不能使用运算符一样。但是,5 + (not True) 有效,这让我相信这是一个解析器问题。

这个错误有什么原因吗?

我找不到与此案例相关的任何资源。

这是一个运算符优先级问题;参见例如this table 在文档中。 +not 绑定得更紧密,因此:

not True + 5

相当于:

not (True + 5)
在这种情况下,

True 的计算结果为 1(因此您得到 True + 5 == 6not 6 == False)。另一方面:

5 + not True

是:

(5 + not) True

这没有任何意义。你需要明确地写:

5 + (not True)

(等于 5,因为 not TrueFalse 并且 False 的计算结果是 0。)

我们需要查看 Python grammar 以了解为什么 not True + 5 在语法上(尽管在语义上不是)有效而 5 + not True 是一个解析错误。以下是最相关的部分:

相关语法规则
inversion:
    | 'not' inversion 
    | comparison

comparison:
    | bitwise_or
bitwise_or:
    | bitwise_xor
bitwise_xor:
    | bitwise_and
bitwise_and:
    | shift_expr
shift_expr:
    | sum

sum:
    | sum '+' term 
    | term

这些规则的顺序与所涉及的各种运算符的优先级相匹配,从最低优先级到最高优先级。 'not' inversion 列在 sum '+' term 之前,因为 not 运算符的优先级低于 +.

not <expr> 被解析为 反转 。按照推导链阅读 top-down,您可以看到 inversion 可以是 sum。这意味着 not True + 5 可以解析为 not 运算符后跟 True + 5.

的操作数
not True + 5
的解析树
inversion
│       │
'not'   inversion
        │
        comparison
        │
        bitwise_or
        │
        bitwise_xor
        │
        bitwise_and
        │
        shift_expr
        │
        sum
        │
        sum '+' term
        │       │
        term    '5'
        │
        'True'

另一方面,如果您有 5 + not True,则无法构建解析树。如果您尝试过,5 + not True 将被解析为 sum '+' term。左边没问题:5 可以解析为 sum。但是右侧没有有效的解析:not True 不是 term.

5 + not True
的解析树失败
sum ─┬────┐
│    │    │
sum  '+'  term
│         │
term      <error: no derivation for 'not' 'True'>
│
'5'

注意:“恢复”语法的唯一方法是添加括号。 not True 不是 ,但是带括号的 (not True) 是。 5 + (not True) 在语法上是有效的。当然,它在语义上仍然是无效的。但是,嘿,如果你不关心语义,解析器不会阻止你。