Согласно моему пониманию интерпретатора perl, код сначала разбирается в код операции. Затем этот граф кода операции интерпретируется во время выполнения. Я хочу знать, происходит ли синтаксический анализ построчно или все вместе.

У меня есть код с оператором exit в начале, но когда я запускаю скрипт, perl сообщает об ошибке, которая находится намного ниже оператора exit. (Ошибка - отсутствие точки с запятой.) Если интерпретатор Perl работает построчно, как он может сообщить об ошибке, которая находится под оператором выхода? Или ошибка сообщается на этапе синтаксического анализа?

1
Anushree Saran 30 Дек 2015 в 22:15

2 ответа

Лучший ответ

Если интерпретатор Perl работает построчно, как он может сообщить об ошибке, которая находится под оператором выхода? Или сообщение об ошибке появляется на этапе синтаксического анализа?

Об этой ошибке было сообщено на этапе синтаксического анализа / компиляции. Об этом было бы сообщено, даже если бы вы использовали -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
3
ikegami 5 Янв 2016 в 19:45

В Perl замечательно то, что компилятор и интерпретатор работают рука об руку. Скомпилированный код может быть выполнен на полпути в процессе компиляции, и интерпретатор может запросить компиляцию кода во время выполнения.

Как правило, программа компилируется посимвольно, а затем выполняется, но если компилятор встречает блок BEGIN (или оператор use, который работает как BEGIN), то Perl интерпретатор вызывается для выполнения этого блока непосредственно перед компиляцией остальной программы

Как только компилятор достигает конца файла, код выполняется интерпретатором. Но среда выполнения Perl может также использовать eval для вызова компилятора.

Если в любом месте основного исходного файла есть фатальная ошибка, например, отсутствие точки с запятой, то компилятор Perl немедленно сообщит об ошибке, прежде чем интерпретатор начнет выполнять скомпилированный код.

2
Borodin 30 Дек 2015 в 23:19