davido has asked for the wisdom of the Perl Monks concerning the following question:

The other day when I was working on Perl's regexp (?{...}) construct and constraining matches. I came across a strange error message. Before I start in, let me state that I'm fully aware that (?{...}) is considered a "highly experimental" feature, and that I should expect quirks. But that said, here's the background:

The following code will produce a runtime warning:

print rand + 5;

The warning will be:

Warning: Use of "rand" without parentheses is ambiguous at mytest.pl line 4 (#1)

This is understandable (though it's one case where whitespace does matter, as "print rand +5;" doesn't trigger a warning), and the information returned from 'use diagnostics' pretty much tells the story:

Warning: Use of "rand" without parentheses is ambiguous at mytest.pl l +ine 4 (#1) (S ambiguous) You wrote a unary operator followed by something tha +t looks like a binary operator that could also have been interpreted + as a term or unary operator. For instance, if you know that the rand function has a default argument of 1.0, and you write rand + 5; you may THINK you wrote the same thing as rand() + 5; but in actual fact, you got rand(+5); So put in parentheses to say what you really mean.

Now look at the following snippet, which commits the same faux pax within a (?{ code }) block of a regular expression:

use strict; use warnings; use diagnostics; my $string = "1230000000"; print $string =~ m/123(?{(pos <= length($_)*.5) ? '(?=)':'(?!)'})(??{$ +^R})/ ? "Matched.\n" : "Didn't match.\n"; __OUTPUT__ Warning: Use of "pos" without parentheses is ambiguous at (re_eval 2) +line 1 (#1 ) (S ambiguous) You wrote a unary operator followed by something tha +t looks like a binary operator that could also have been interpreted + as a term or unary operator. For instance, if you know that the rand function has a default argument of 1.0, and you write rand + 5; you may THINK you wrote the same thing as rand() + 5; but in actual fact, you got rand(+5); So put in parentheses to say what you really mean. panic: top_env

Again, the same warning, and the same diagnostic message: no problem. But what's with the "panic:  top_env" message? And why doesn't it print out a diagnostic too?

Looking in perldiag I found the following:

(P) An internal error you should never see (trappable).
....
panic: top_env
(P) The compiler attempted to do a goto, or something weird like that.

First, what is this? Second, since I "should never see" this, does the fact that I am seeing it indicate that I should submit a perlbug report?

With similar snippets I've also managed to trigger the following similar error:

panic: restartop (P) Some internal routine requested a goto (or something like it), and + didn't supply the destination.

Though I can't remember how to reproduce the latter, they seem related. I cannot help but think that if I'm seeing these sorts of messages, there is a loose end somewhere in Perl that needs to be tied up. Any voices of agreement or disagreement?


Dave

Replies are listed 'Best First'.
Re: "panic: top_env": Is this error resulting from a Perl bug?
by ysth (Canon) on Aug 15, 2004 at 07:53 UTC
    Any panic: is by definition a perl bug, as perldiag says. Before reporting it, if possible see if it is still a problem with the latest maintenance release (n.b. make sure it's built with the same options before dismissing the bug as "fixed"), and if it has not already been reported. Both appear to be true in this case.

    It's helpful to get the test case as short as possible. In this case: ./perl -e'qr/(?{rand < 5})/' shows the bug (but rand + 5 doesn't). Note that it happens at compile time, not run time.

Re: "panic: top_env": Is this error resulting from a Perl bug?
by ysth (Canon) on Aug 15, 2004 at 15:15 UTC
    But what's with the "panic: top_env" message? And why doesn't it print out a diagnostic too?
    This panic: message doesn't actually seem to be implemented as a warn or die; it just does the equivalent of print STDERR "panic: top_env\n"; and then bails out of the parser with an error. Perhaps this is also a bug :)

    You can still get the diagnostics by piping STDERR to the splain utility:

    $ perl -e'qr/(?{rand < 5})/' 2>&1 |splain Warning: Use of "rand" without parentheses is ambiguous at (re_eval 1) + line 1 (# 1) (S ambiguous) You wrote a unary operator followed by something tha +t looks like a binary operator that could also have been interpreted + as a term or unary operator. For instance, if you know that the rand function has a default argument of 1.0, and you write rand + 5; you may THINK you wrote the same thing as rand() + 5; but in actual fact, you got rand(+5); So put in parentheses to say what you really mean. panic: top_env (#2) (P) The compiler attempted to do a goto, or something weird like t +hat.

      Usually when perl panics, it lacks confidence in the integrity of its internal state and therefore tries to require as little as possible of itself to get the error message out.

      For example, things like "panic: out of memory" would be little use if they went through a path that tried to allocate memory.

      Hugo

Re: "panic: top_env": Is this error resulting from a Perl bug?
by Aristotle (Chancellor) on Aug 16, 2004 at 01:06 UTC

    Just for the sake of those reading the thread, who're not suspecting this: once one adds the parentheses the warning demands, the panic message disappears as well.

    Apparently, the compiler doesn't recover gracefully from generating the warning when it's in the middle of compiling a regular expression.

    Makeshifts last the longest.

Re: "panic: top_env": Is this error resulting from a Perl bug?
by ysth (Canon) on Aug 15, 2004 at 22:04 UTC
    Doing a simple search here for panic: top_env failed because there's a node with that exact name :)   However, there you will find a link to an earlier discussion of this here.