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

发布于 2025-01-12 10:00:27 字数 272 浏览 0 评论 0原文

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

这个错误有什么原因吗?

  • 这是语言做出的设计决定吗?
  • 这是解析器错误,还是语言规则未定义的行为?

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

Today, I noticed that not True + 5 is syntactically valid but 5 + not True isn't.
The syntax error points to the first character of not, as if the operator couldn't be used here. However, 5 + (not True) works, which leads me to believe it is a parser issue.

Are there any reasons for this error?

  • Is it a design decision taken by the language?
  • Is it is a parser error, or a behaviour not defined by the language's rules?

I couldn't find any resources concerning this case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小女人ら 2025-01-19 10:00:27

我们需要查看 Python 语法 来了解为什么 不为 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 被解析为反转。按照推导链自上而下地阅读,您可以看到反转可以是求和。这意味着 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 不是一个术语

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

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

We need to look at the Python grammar to see why not True + 5 is syntactically (though not semantically) valid while 5 + not True is a parse error. Here are the most relevant portions:

Relevant grammar rules
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

The order of these rules matches precedence of the various operators involved, from lowest precedence to highest. 'not' inversion is listed before sum '+' term because the not operator has lower precedence than +.

not <expr> is parsed as an inversion. Reading top-down following the chain of derivations, you can see that an inversion could be a sum. This means that not True + 5 can be parsed as the not operator followed by an operand of True + 5.

Parse tree for not True + 5
inversion
│       │
'not'   inversion
        │
        comparison
        │
        bitwise_or
        │
        bitwise_xor
        │
        bitwise_and
        │
        shift_expr
        │
        sum
        │
        sum '+' term
        │       │
        term    '5'
        │
        'True'

On the other hand if you have 5 + not True there is no way to construct a parse tree. If you tried, 5 + not True would be parsed as sum '+' term. The left side is fine: 5 can be parsed as a sum. There's no valid parse for the right side, though: not True is not a term.

Failed parse tree for 5 + not True
sum ─┬────┐
│    │    │
sum  '+'  term
│         │
term      <error: no derivation for 'not' 'True'>
│
'5'

NB: The only way to work back "up" the grammar is to add parentheses. not True is not a term, but (not True) with parentheses is. 5 + (not True) is syntactically valid. Of course, it's still semantically invalid. But hey, if you don't care about semantics the parser won't stop you.

冷了相思 2025-01-19 10:00:27

这是一个运算符优先级问题;请参阅文档中的此表+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 TrueFalse 并且 False 的计算结果为<代码>0。)

It's an operator precedence issue; see e.g. this table in the documentation. + binds more tightly than not, so this:

not True + 5

Is equivalent to:

not (True + 5)

And True evaluates as 1 in this case (so you get True + 5 == 6, and not 6 == False). On the other hand:

5 + not True

Is:

(5 + not) True

Which doesn't make any sense. You would need to explicitly write:

5 + (not True)

(Which would equal 5, since not True is False and False evaluates to 0.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文