Что означает «Ошибка: незаконное объявление подпрограммы»? - PullRequest
2 голосов
/ 05 июля 2010

Я получил ошибку от моего модуля Perl "Ошибка: незаконное объявление подпрограммы". Что это значит? Я попробовал поискать его и получил следующую бесполезную информацию :

Произошла новая ошибка компиляции, Незаконное объявление подпрограммы, для неясный случай синтаксических ошибок.

Код, вызвавший ошибку, выглядит так (усечено, чтобы показать проблему):

    $dbh->do ($stm); # ACTUAL ERROR IS THE SEMICOLON HERE
    or croak "Can't insert using '$stm': ", $dbh->errstr;
    return $dbh->last_insert_id ('', '', '', '');
}

sub insert_check # ERROR MESSAGE IS PRINTED FOR THIS LINE
{
    my ($dba, $table, $set) = @_;

Ответы [ 2 ]

4 голосов
/ 05 июля 2010

Это недопустимый код Perl: 'or' является инфиксным оператором, поэтому он не может начать оператор.

Исправьте код (или код, который его сгенерировал), удалив ';'и ошибка исчезнет.

0 голосов
/ 26 августа 2010

Заполнение достаточного количества пробелов, чтобы воспроизвести проблему

 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.

Как видите, первая ошибка является результатом случайной точки с запятой. Что касается грамматики Perl, строка 6 синтаксически верна.

Как правило, вы хотите начать исправление синтаксических ошибок с ошибки first из-за распространенного метода реализации синтаксических анализаторов. Представьте себе работу с компилятором, который диагностирует только первую обнаруженную ошибку. «Я почти у цели!», Вы можете подумать, что будете разочарованы только следующей пробежкой, а затем следующей, следующей и следующей. Чтобы не расстраивать пользователей и толкать некоторых через край, парсеры делают все возможное, чтобы продолжить, как описано на стр. 205 из flex & bison :

Восстановление после ошибки Bison

Bison имеет некоторые положения для восстановления после ошибок, которые доступны с помощью специального маркера ошибки. По сути, токен ошибки используется для нахождения точки синхронизации в грамматике, из которой вероятно, что обработка может продолжаться. Это вероятно , не уверен. Иногда попытки восстановления не удалят достаточно ошибочного состояния, чтобы продолжить, и сообщения об ошибках будут каскадными. Либо синтаксический анализатор достигнет точки, с которой обработка может продолжиться, либо весь анализатор прекратит работу.

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

Обратите внимание, что bison участвует в создании парсера perl .

Если вам интересно узнать, в каком состоянии находится парсер после повторной синхронизации, запустите perl, созданный с DEBUGGING, с опцией -Dp или -Dpv :

-Dletters

-Dnumber

устанавливает флаги отладки. Чтобы посмотреть, как она выполняет вашу программу, используйте -Dtls. (Это работает, только если отладка скомпилирована в ваш Perl.) Еще одно приятное значение - -Dx, которое перечисляет ваше скомпилированное синтаксическое дерево. И -Dr отображает скомпилированные регулярные выражения; формат вывода объясняется в perldebguts .

В качестве альтернативы укажите число вместо списка букв (например, -D14 эквивалентно -Dtls):

1 p Токенизация и синтаксический анализ (с v, отображает стек разбора)
...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...