Perl 什么是;错误:非法声明子例程“;意味着什么?

Perl 什么是;错误:非法声明子例程“;意味着什么?,perl,Perl,我从Perl模块“error:非法声明子例程”中得到一个错误。这是什么意思?我试着在谷歌上搜索,结果得到: 有一个新的编译错误, 子程序的非法声明,例如 一个模糊的语法错误案例 导致错误的代码如下(截断以显示问题): 这是非法的Perl代码:“or”是中缀运算符,因此无法启动语句 通过删除“;”来修复代码(或生成代码的代码)错误就会消失。填补足够的空白,重现问题 1 #! /usr/bin/perl 2 3 use Carp; 4 5 sub foo { 6

我从Perl模块“error:非法声明子例程”中得到一个错误。这是什么意思?我试着在谷歌上搜索,结果得到:

有一个新的编译错误, 子程序的非法声明,例如 一个模糊的语法错误案例

导致错误的代码如下(截断以显示问题):


这是非法的Perl代码:“or”是中缀运算符,因此无法启动语句


通过删除“;”来修复代码(或生成代码的代码)错误就会消失。

填补足够的空白,重现问题

 1  #! /usr/bin/perl
 2  
 3  use Carp;
 4  
 5  sub foo {
 6      $dbh->do ($stm);
 7      or croak "Can't insert using '$stm': ", $dbh->errstr;
 8      return $dbh->last_insert_id ('', '', '', '');
 9  }
10  
11  sub insert_check
12  {
13      my ($dba, $table, $set) = @_;
14  }
然后把它输入编译器,我得到

$ perl5.10.1 -cw kinopiko.pl syntax error at prog.pl line 7, near "or" Illegal declaration of subroutine main::insert_check at prog.pl line 11. 每5.10.1美元-cw kinopiko.pl prog.pl第7行“or”附近的语法错误 子程序main::insert_check在prog.pl第11行的非法声明。 正如您所看到的,第一个错误是错误的分号造成的。就Perl语法而言,第6行在语法上是正确的

通常,您希望在第一个错误时就开始修复语法错误,因为这是一种实现解析器的常见技术。想象一下,使用一个只诊断它遇到的第一个错误的编译器我快到了你只会觉得对下一轮、下一轮、下一轮、下一轮感到失望。为了避免让用户感到沮丧并将一些人推到边缘,解析器会尽最大努力继续,如所述:

野牛错误恢复 Bison对错误恢复有一些规定,可以通过使用专用错误令牌来实现。从本质上讲,错误标记用于在语法中查找一个同步点,处理可能从该同步点继续。这很可能,不确定。有时,恢复尝试将无法删除足够的错误状态以继续,错误消息将级联。要么解析器将到达处理可以继续的点,要么整个解析器将中止

报告语法错误后,bison解析器将丢弃解析堆栈中的符号,直到找到可以移动错误标记的状态。然后,它读取并丢弃输入标记,直到找到一个可以跟随语法中的错误标记。后一个过程称为重新同步。然后,它会在恢复状态下恢复解析,而不会报告后续的解析错误。一旦成功转移了三个令牌,它就假定恢复已完成,离开恢复状态,并恢复正常解析

请注意,
野牛
参与了这一过程

如果您对重新同步后解析器会处于什么样的怪诞状态很感兴趣,可以启动一个
perl
内置的
调试
选项:

-德莱特斯 -数字 设置调试标志。要查看它如何执行程序,请使用
-Dtls
。(这仅在将调试编译到Perl中时有效。)另一个很好的值是
-Dx
,它列出了编译后的语法树。和
-Dr
显示已编译的正则表达式;输出的格式如中所述

或者,指定一个数字而不是字母列表(例如,
-D14
相当于
-Dtls
):

1 p标记化和解析(使用v,显示解析堆栈)


也许如果你发布了生成它的代码?你这一行后面的内容是什么?@Yuji:我会添加信息,但这不会有任何区别,错误信息会针对那一行打印出来,如果分号被删除,它会再次消失。可能是前面的语法错误导致解析代码的东西认为你在另一个函数中声明了一个函数,因为它的状态机关闭了。@jeffamaphone:请看#注释。我想要一副你戴的眼镜@冯肖恩:我刚才把它们弄丢了。但是我的新的是相似的。如果你去Pisa的YAPC::Europe,我们可以安排一些事情。 $ perl5.10.1 -cw kinopiko.pl syntax error at prog.pl line 7, near "or" Illegal declaration of subroutine main::insert_check at prog.pl line 11.