简体   繁体   English

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

[英]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.但是,它编译和执行时没有警告,退出时错误级别为零。 How is this valid syntax?这个有效的语法如何?

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)

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 -object 调用方法Syntax ......确实很奇怪!

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

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)导致程序死亡(这就是我所做的)

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

In this paper , we aim to answer a long-standing open problem in the programming languages community: is it possible to smear paint on the wall without creating valid Perl?本文中,我们旨在回答编程语言社区中一个长期存在的悬而未决的问题:是否可以在不创建有效 Perl 的情况下在墙上涂抹油漆?

TLDR; TLDR; Hardly几乎不

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在我的代码生成程序中出现此语法错误? - Why do I get this syntax error in my code generating program? 为什么在尝试显示源时出现.perldb别名语法错误? - Why do I get .perldb alias syntax error when trying to display source? 为什么即使我的SQLite版本支持`CREATE TABLE IF NOT EXISTS`,我仍会收到DBD :: SQLite语法错误? - Why do I get a syntax error with DBD::SQLite even though my version of SQLite supports `CREATE TABLE IF NOT EXISTS`? 当我使用“given”时为什么会出现语法错误? - Why do I get a syntax error when I use “given”? 为什么此eval出现语法错误? - Why is there a syntax error with this eval? 为什么(a =&gt; 1,b =&gt; 2){a}语法错误? - Why is (a=>1,b=>2){a} a syntax error? 为什么“keys ::”不是语法错误? - Why is “keys ::” not a syntax error? 为什么这是SQL语法错误? - Why is this a SQL syntax error? 为什么在此Perl代码中出现“&#39;$ rocks [&#39;附近的语法错误””? - Why do I get “Syntax error near '$rocks['” in this Perl code? 当我尝试创建具有外键约束的SQLite表时,为什么会出现“ DBD :: SQLite :: db失败:靠近“事务”:语法错误”的问题? - Why do I get 'DBD::SQLite::db do failed: near “transaction”: syntax error' when I try to create a SQLite table with a foreign key constraint?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM