gpt4 book ai didi

perl - Perl 中的 `null vK` 是什么?

转载 作者:行者123 更新时间:2023-12-05 00:34:33 34 4
gpt4 key购买 nike

使用 Perl,我有两个相似的语法,

if ($a && $b) { exit() }
do { exit() } if ($a && $b)

我相信这些应该是同一件事,但是最上面的一个创建了 null vK操作码,
<1> null vK*/1 ->-
null vK有什么意义它有什么作用?
$ perl -MO=Concise -e'if ($a && $b) { exit() }'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
- <1> null vK/1 ->8
6 <|> and(other->7) vK/1 ->8
- <1> null sK/1 ->6
4 <|> and(other->5) sK/1 ->8
- <1> ex-rv2sv sK/1 ->4
3 <#> gvsv[*a] s ->4
- <1> ex-rv2sv sK/1 ->-
5 <#> gvsv[*b] s ->6
- <@> scope vK ->-
- <;> ex-nextstate(main 3 -e:1) v ->7
7 <0> exit v* ->8
-e syntax OK

诗句如下,
$ perl -MO=Concise -e'do { exit() } if ($a && $b)'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
- <1> null vK/1 ->8
6 <|> and(other->7) vK/1 ->8
- <1> null sKP/1 ->6
4 <|> and(other->5) sK/1 ->8
- <1> ex-rv2sv sK/1 ->4
3 <#> gvsv[*a] s ->4
- <1> ex-rv2sv sK/1 ->-
5 <#> gvsv[*b] s ->6
- <1> null vK*/1 ->-
- <@> scope vK ->-
- <;> ex-nextstate(main 2 -e:1) v ->7
7 <0> exit v* ->8

最佳答案

行首的“-”表示操作不会被执行,这也可以使用 perl -MO=Concise,-exec 看到。 .

也就是说,null vK...null sK... B::Concise 输出中的操作码并不意味着某些操作已被优化掉。 perldoc在 B::Concise 上清楚地表明这种优化是由 ex- 指示的。在输出中:

Nullops appear as "ex-opname", where opname is an op that has been optimized away by perl. They're displayed with a sequence-number of '-', because they are not executed (they don't appear in previous example), they're printed here because they reflect the parse.



例如:
> perl  -MO=Concise -e "$a"
4 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
- **<1> ex-rv2sv vK/1 ->4**
3 <#> gvsv[*a] s ->4

那么那些空值是什么呢?

它们是来自 Perl 用来解析代码的 yacc 语法的真正空值,并且它们从一开始就没有打算执行。

在你的情况下,多余的 null vk直接来自以下 do BLOCK语法规则( perly.y ):
termdo  :       DO term %prec UNIOP                     /* do $filename */
{ $$ = dofile($2, $1);}
| DO block %prec '(' /* do { code */
{ $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($2));}
;

我们可以在这里看到:
>perl -MO=Concise -e "do{}"
4 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 2 -e:1) v:{ ->3
- <1> null vK*/1 ->4
- <@> scope vK ->-
3 <0> stub v ->4

在其他情况下,空值来自 yacc 操作。
显然,这些空值用于帮助管理操作树,并且由于它们从未被执行,我认为 Perl 开发人员不会在意它们的存在。

下面是一个由 bool 表达式解析产生的空操作示例:
>perl  -MO=Concise -e "$a||$b"
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
- <1> null vK/1 ->6
4 <|> or(other->5) vK/1 ->6
- <1> ex-rv2sv sK/1 ->4
3 <#> gvsv[*a] s ->4
- <1> ex-rv2sv vK/1 ->-
5 <#> gvsv[*b] s ->6

为什么这里是空值?另一个片段有助于澄清:
>perl -MO=Concise -e "!$a&&!$b"
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <1> not vK/1 ->7
4 <|> or(other->5) sK/1 ->6
- <1> ex-not sK/1 ->4
- <1> ex-rv2sv sK/1 ->-
3 <#> gvsv[*a] s ->4
- <1> ex-not sK/1 ->6
- <1> ex-rv2sv sK/1 ->-
5 <#> gvsv[*b] s ->6

看来 null vK已成为 not vK .
仔细看,我们可以看到 Perl 优化了 !$a&&!$b进入 !($a||$b)not(!)代替 null .
事实证明,Perl 总是为逻辑表达式保留一个父操作码,如果表达式可以用外层 not 简化
Perl 看跌期权 not进入父操作码,和 null除此以外。

总结一下:由 ex- 指示的 NULL 操作码在 B::Concise输出由优化器生成,而 NULL 操作码由 null 指示来自语法解析器。它们都不会被执行,也不会受到性能处罚。

关于perl - Perl 中的 `null vK` 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49663071/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com