Filling in enough of the gaps to reproduce the problem
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 }
and then feeding it to the compiler, I get
$ 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.
As you can see, the first error is a result of the stray semicolon. As far as Perl's grammar is concerned, line 6 is syntactically correct.
In general, you want to begin fixing syntax errors at the first error because of a common technique for implementing parsers. Imagine working with a compiler that diagnoses only the first error it encounters. ‘I’m almost there!’ you'd think only to be disappointed by the next run—and then the next and the next and the next. To avoid frustrating users and pushing a few over the edge, parsers do their best to continue as described on page 205 of flex & bison:
Bison Error Recovery
Bison has some provisions for error recovery, which are available by using the special-purpose error token. Essentially, the error token is used to find a synchronization point in the grammar from which it is likely that processing can continue. That's likely, not certain. Sometimes attempts at recovery will not remove enough of the erroneous state to continue, and the error messages will cascade. Either the parser will reach a point from which processing can continue or the entire parser will abort.
After reporting a syntax error, a bison parser discards symbols from the parse stack until it finds a state which it can shift an error token. It then reads and discards input tokens until it finds one that can follow the error token in the grammar. This latter process is called resynchronizing. It then resumes parsing in a recovering state, which doesn't report subsequent parse errors. Once it has shifted three tokens successfully, it presumes that recovery is complete, leaves the recovery state, and resumes normal parsing.
Note that bison
is involved in generating perl's parser.
If you're curious enough to dig into what whacko state the parser finds itself in after resynchronization, fire up a perl
built with DEBUGGING
with the -Dp
or -Dpv
option:
-Dletters
-Dnumber
sets debugging flags. To watch how it executes your program, use -Dtls
. (This works only if debugging is compiled into your Perl.) Another nice value is -Dx
, which lists your compiled syntax tree. And -Dr
displays compiled regular expressions; the format of the output is explained in perldebguts.
As an alternative, specify a number instead of list of letters (e.g., -D14
is equivalent to -Dtls
):
1 p Tokenizing and parsing (with v, displays parse stack)
…