为什么在语法上无效的加法之后是逻辑不?
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 == 6
和 not 6 == False
)。另一方面:
5 + not True
是:
(5 + not) True
这没有任何意义。你需要明确地写:
5 + (not True)
(等于 5
,因为 not True
是 False
并且 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)
在语法上是有效的。当然,它在语义上仍然是无效的。但是,嘿,如果你不关心语义,解析器不会阻止你。
今天,我注意到 not True + 5
在语法上是有效的,但 5 + not True
不是。
语法错误指向 not 的第一个字符,就好像这里不能使用运算符一样。但是,5 + (not True)
有效,这让我相信这是一个解析器问题。
这个错误有什么原因吗?
- 这是语言做出的设计决定吗?
- 这是解析器错误,还是语言规则未定义的行为?
我找不到与此案例相关的任何资源。
这是一个运算符优先级问题;参见例如this table 在文档中。 +
比 not
绑定得更紧密,因此:
not True + 5
相当于:
not (True + 5)
在这种情况下, 和 True
的计算结果为 1
(因此您得到 True + 5 == 6
和 not 6 == False
)。另一方面:
5 + not True
是:
(5 + not) True
这没有任何意义。你需要明确地写:
5 + (not True)
(等于 5
,因为 not True
是 False
并且 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)
在语法上是有效的。当然,它在语义上仍然是无效的。但是,嘿,如果你不关心语义,解析器不会阻止你。