为什么这个程序有效?我试图创建一个语法错误

本文翻译自:Why is this program valid? I was trying to create a syntax error

I'm running ActiveState's 32 bit ActivePerl 5.14.2 on Windows 7. I wanted to mess around with a Git pre-commit hook to detect programs being checked in with syntax errors. 我在Windows 7上运行ActiveState的32位ActivePerl 5.14.2。我想用Git预提交钩子来检测正在检查的语法错误的程序。 (Somehow I just managed to do such a bad commit.) So as a test program I randomly jotted this: (不知怎的,我只是设法做了这么糟糕的提交。)所以作为一个测试程序,我随机记下了这个:

use strict;
use warnings;

Syntax error!

exit 0;

However, it compiles and executes with no warnings, and errorlevel is zero on exit. 但是,它在没有警告的情况下编译和执行,退出时errorlevel为零。 How is this valid syntax? 这个有效的语法怎么样?


#1楼

参考:https://stackoom.com/question/n4Qo/为什么这个程序有效-我试图创建一个语法错误


#2楼

I don't know why, but this is what Perl makes of it: 我不知道为什么,但这就是Perl所做的:

perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
'error'->Syntax(!exit(0));
yuck syntax OK

It seems that the parser thinks you're calling the method Syntax on the error -object... Strange indeed! 似乎解析器认为你在error上调用方法Syntax ......确实是奇怪的!


#3楼

Perl has a syntax called "indirect method notation". Perl有一种称为“间接方法表示法”的语法。 It allows 它允许

Foo->new($bar)

to be written as 写成

new Foo $bar

So that means 这意味着

Syntax error ! exit 0;

is the same as 是相同的

error->Syntax(! exit 0);

or 要么

error->Syntax(!exit(0));

Not only is it valid syntax, it doesn't result in a run-time error because the first thing executed is exit(0) . 它不仅是有效的语法,它不会导致运行时错误,因为执行的第一件事是exit(0)


#4楼

The reason you do not get an error is that the first executed code is 您没有收到错误的原因是第一个执行的代码是

exit(0);

Because you did not have a semicolon on the first line: 因为第一行没有分号:

Syntax error!

The compiler will guess (incorrectly) that this is a subroutine call with a not operator ! 编译器会猜测(错误地)这是一个使用not运算符的子程序调用! thrown in. It will then execute the arguments to this subroutine, which happens to be exit(0) , at which point the program exits and sets errorlevel to 0. Nothing else is executed, so no more runtime errors are reported. 然后它将执行该子例程的参数,该子例程恰好是exit(0) ,此时程序退出并将errorlevel设置为0.没有其他任何执行,因此不会报告更多的运行时错误。

You will notice that if you change exit(0) to something like print "Hello world!" 您会注意到,如果您将exit(0)更改为print "Hello world!" you do get an error: 你收到一个错误:

Can't locate object method "Syntax" via package "error" ...

and your error level will be set: 并将设置您的错误级别:

> echo %errorlevel%
255

#5楼

As noted above this is caused by the indirect method calling notation. 如上所述,这是由间接方法调用符号引起的。 You can warn on this: 你可以警告:

use strict;
use warnings;
no indirect;

Syntax error!

exit 0;

Produces: 生产:

Indirect call of method "Syntax" on object "error" at - line 5.

This requires the indirect CPAN module . 这需要间接CPAN模块

You can also use no indirect "fatal"; 你也可以no indirect "fatal";使用no indirect "fatal"; to cause the program to die (this is what I do) 导致程序死亡(这就是我所做的)


#6楼

Try Perl 6 , it seems to fulfill your expectations more readily: 尝试Perl 6 ,它似乎更容易满足您的期望:

===SORRY!=== Error while compiling synerror.p6
Negation metaoperator not followed by valid infix
at synerror.p6:1
------> Syntax error!⏏<EOL>
    expecting any of:
        infix
        infix stopper
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值