develooper Front page | perl.perl5.porters | Postings from May 2004

Re: [perl #28966] Syntax error in Switch.pm

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
May 16, 2004 08:52
Subject:
Re: [perl #28966] Syntax error in Switch.pm
Message ID:
20040516155754.GA1905@iabyn.com
On Mon, Apr 19, 2004 at 05:20:34PM -0000, Loic Minier wrote:
>  User of the Switch package, I noticed a strange behavior with very
>  simple regexps.
> 
>  When I try to run this simple program:
> 
>     #!/usr/bin/perl -w
>     use strict;
>     use Switch;
>     switch ('foo') {
>        case /^bar\s+\S+/ {
>            # +
>        }
>     }
>  (please note the comment)
>  ... I get:
>     syntax error at ./buggy.pl line 7, near "}continue"
>     syntax error at ./buggy.pl line 8, near "}"
>     Execution of ./buggy.pl aborted due to compilation errors.
> 
>  Removing the comment stops the barking.

Thanks for the report, and sorry for the delay in replying. The short
answer is that its fixed by the patch below to Text::Balanced that's been
applied to the development version of Perl. Whether and how this fix makes
it into the CPAN version is up to the module's maintainer, Damian.
Damian?

The long answer:
Switch uses Text::Balanced::_match_codeblock to extract out the block of
text corresponding to

    {
       case /^bar\s+\S+/ {
           # +
       }
    }

but it runs into problems with the bareword 'case' followed by the bare
pattern match //. In general, does

    foo /2 ...

indicate

call foo() then divide by 2, then ...
or match $_ against /2.../ and pass the result to foo()?

How Perl interprets this depends upon such things as whether foo is a
builtin, or has been previously declared, or whether its a constant
sub, or whether its an indirect object like a filehandle in a print etc
etc.

In general, _match_codeblock() can't possibly disambiguate this; at the
moment it assumes the thing following is an operator except for
a few special-cased barewords like split and grep. I've added 'case'
to this list of exceptions. This menas it now sees the /.../ thing
following the 'case' as a regex to be skipped over.

Dave.



-- 
Wesley Crusher gets beaten up by his classmates for being a smarmy git,
and consequently has a go at making some friends of his own age for a
change.
    -- Things That Never Happen in "Star Trek" #18


Change 22821 by davem@davem-percy on 2004/05/16 15:31:42

	make Text::Balanced skip "case /..../" correctly for Switch.pm

Affected files ...

... //depot/perl/lib/Text/Balanced.pm#9 edit
... //depot/perl/lib/Text/Balanced/t/extcbk.t#4 edit

Differences ...

==== //depot/perl/lib/Text/Balanced.pm#9 (text) ====

@@ -10,7 +10,7 @@
 use SelfLoader;
 use vars qw { $VERSION @ISA %EXPORT_TAGS };
 
-$VERSION = '1.95';
+$VERSION = '1.95_01';
 @ISA		= qw ( Exporter );
 		     
 %EXPORT_TAGS	= ( ALL => [ qw(
@@ -583,12 +583,15 @@
 
 
 		# NEED TO COVER MANY MORE CASES HERE!!!
+		# NB 'case' is included here, because in Switch.pm,
+		# it's followed by a term, not an op
+
 		if ($$textref =~ m#\G\s*(?!$ldel_inner)
 					( [-+*x/%^&|.]=?
 					| [!=]~
 					| =(?!>)
 					| (\*\*|&&|\|\||<<|>>)=?
-					| split|grep|map|return
+					| case|split|grep|map|return
 					| [([]
 					)#gcx)
 		{

==== //depot/perl/lib/Text/Balanced/t/extcbk.t#4 (text) ====

@@ -13,7 +13,7 @@
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
-BEGIN { $| = 1; print "1..41\n"; }
+BEGIN { $| = 1; print "1..43\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_codeblock );
 $loaded = 1;
@@ -64,6 +64,7 @@
 
 # USING: extract_codeblock($str);
 { $data[4] =~ /['"]/; };
+{ case /^bar\s+\S+/ {\n#+\n}};
 
 # USING: extract_codeblock($str,'<>');
 < %x = ( try => "this") >;

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About