根据我对perl解释器的理解,代码首先被解析为操作码。然后在执行期间解释此操作码图。我想知道解析是逐行还是一起发生。
我在开头有一些带有exit
语句的代码,但是当我运行脚本时,perl报告的错误位于exit
语句之下。 (错误是缺少分号。)如果perl解释器逐行工作,它如何报告位于exit语句下面的错误?或者是在解析阶段报告错误?
答案 0 :(得分:3)
如果perl解释器逐行工作,它如何报告位于exit语句下面的错误?或者是在解析阶段报告错误?
在解析/编译阶段报告了有问题的错误。即使您使用-c
,也会报告。这些被称为"编译时错误"。
在该阶段无法检测到某些错误。这些被称为"运行时错误"。
根据我对perl解释器的理解,代码首先被解析为操作码。然后在执行期间解释此操作码图。我想知道解析是逐行还是全部解析。
将文件编译为一个整体,然后从头开始执行编译的表单。 BEGIN
和use
语句与此不同;它们在编译后立即执行(即在编译文件的其余部分之前)。
$ perl -e'
BEGIN { print "Start of compilation.\n"; }
print "Start of execution.\n";
# ...
BEGIN { print "End of compilation.\n"; }
print "End of execution.\n";
'
Start of compilation.
End of compilation.
Start of execution.
End of execution.
使用-c
会导致Perl在开始执行之前退出。 (BEGIN
和use
语句仍然正常执行。)
$ perl -c -e'
print "This statement was executed.\n"
my $x = 4;
$x += 5;
print "$x\n";
BEGIN { print "This statement was compiled.\n"; }
'
This statement was compiled.
-e syntax OK
以下是编译结果的类似内容:
$ perl -MO=Concise,-exec -e'
my $x = 4;
$x += 5;
print "$x\n";
'
1 <0> enter
2 <;> nextstate(main 1 -e:2) v:{
3 <$> const[IV 4] s
4 <0> padsv[$x:1,2] sRM*/LVINTRO
5 <2> sassign vKS/2
6 <;> nextstate(main 2 -e:3) v:{
7 <0> padsv[$x:1,2] sRM
8 <$> const[IV 5] s
9 <2> add[t2] vKS/2
a <;> nextstate(main 2 -e:4) v:{
b <0> pushmark s
c <0> padsv[$x:1,2] s
d <$> const[PV "\n"] s
e <2> concat[t3] sK/2
f <@> print vK
g <@> leave[1 ref] vKP/REFC
-e syntax OK
答案 1 :(得分:2)
Perl的优点在于编译器和解释器是一起工作的。编译代码可以在编译过程中部分执行,解释器可以要求在运行时编译代码
通常,程序是逐个字符编译然后执行的,但是如果编译器遇到BEGIN
块(或use
语句,其作用类似于BEGIN
)然后调用Perl解释器在编译程序的其余部分之前立即执行该块
编译器到达文件末尾后,代码由thge解释器执行。但是运行时Perl也可以使用eval
来调用编译器
如果主源文件中的任何地方都存在致命错误,例如缺少分号,那么Perl编译器将在解释器开始执行编译代码之前立即报告错误