python小菜
2012-07-27 20:19
采纳率: 0%
浏览 228

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

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. (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. How is this valid syntax?

转载于:https://stackoverflow.com/questions/11695110/why-is-this-program-valid-i-was-trying-to-create-a-syntax-error

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • 撒拉嘿哟木头 2012-07-27 20:36
    已采纳

    Perl has a syntax called "indirect method notation". 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).

    点赞 打赏 评论
  • 狐狸.fox 2012-07-27 20:26

    I don't know why, but this is what Perl makes of it:

    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!

    点赞 打赏 评论
  • 狐狸.fox 2012-07-27 20:36

    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 ! 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.

    You will notice that if you change exit(0) to something like 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
    
    点赞 打赏 评论
  • ?yb? 2014-04-03 14:07

    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.

    You can also use no indirect "fatal"; to cause the program to die (this is what I do)

    点赞 打赏 评论
  • from.. 2016-02-05 21:00

    Try Perl 6, it seems to fulfill your expectations more readily:

    ===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
    
    点赞 打赏 评论

相关推荐 更多相似问题