Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

/(?{CODE})?/ #5712

Open
p5pRT opened this issue Jul 11, 2002 · 7 comments
Open

/(?{CODE})?/ #5712

p5pRT opened this issue Jul 11, 2002 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 11, 2002

Migrated from rt.perl.org#10040 (status was 'open')

Searchable as RT10040$

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2002

From @Abigail

Created by @Abigail

  $ perl -wle '/(?{1})?/'

results in

  Quantifier unexpected on zero-length expression in regex;
  marked by <-- HERE in m/(?{1})? <-- HERE / at -e line 1.

While this is a useful (fatal) error for expressions without side-effects,
it's a nuisance for expressions with side-effects. And doing a (?{ })
without side-effects is kind of useless...

The Perl regex machine is a nice framework to do backtracking with. And
then it would be useful to be able to do​:

  (?{ CODE })?

There is a workaround of course​:

  (?​:(?{ CODE })|)

but that's more verbose.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.8.0:
    
Configured by abigail at Fri Jun 21 18:20:52 CEST 2002.

Summary of my perl5 (revision 5.0 version 8 subversion 0 patch 17339) configurat
ion:
  Platform:
    osname=linux, osvers=2.4.5, archname=i686-linux-64int-ld
    uname='linux hermione 2.4.5 #6 fri jun 22 01:38:20 pdt 2001 i686 unknown '
    config_args='-des -Uversiononly -Dmydomain=.foad.org -Dcf_email=abigail@foad
..org -Dperladmin=abigail@foad.org -Doptimize=-g -Dusemorebits -Dusedevel -Dusenm
=false -Darchlib=/opt/perl/5.8.0-RC2/lib/5.8.0-RC2/i686-linux -Dprivlib=/opt/per
l/5.8.0-RC2/lib/5.8.0-RC2 -Dman1dir=/opt/perl/5.8.0-RC2/man/man1 -Dman3dir=/opt/
perl/5.8.0-RC2/man/man3 -Dprefix=/opt/perl/5.8.0-RC2'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=unde
f
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=define
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include -I/
opt/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-g',
    cppflags='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include -I/opt/local
/include'
    ccversion='', gccversion='2.95.3 20010315 (release)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='long double', nvsize=12, Off_t='off_t'
, lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib -L/opt/local/lib'
    libpth=/usr/local/lib /opt/local/lib /lib /usr/lib 
    libs=-lnsl -lndbm -lgdbm -ldl -lm -lc -lcrypt -lutil
    perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
    libc=/lib/libc-2.2.3.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.2.3'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib -L/opt/local/lib'   

Locally applied patches:
    DEVEL17339


@INC for perl v5.8.0:
    /home/abigail/Perl
    /home/abigail/Sybase
    /opt/perl/5.8.0-RC2/lib/5.8.0-RC2/i686-linux
    /opt/perl/5.8.0-RC2/lib/5.8.0-RC2 
    /opt/perl/5.8.0-RC2/lib/site_perl/5.8.0/i686-linux-64int-ld
    /opt/perl/5.8.0-RC2/lib/site_perl/5.8.0
    /opt/perl/5.8.0-RC2/lib/site_perl
    .
    

Environment for perl v5.8.0:
    HOME=/home/abigail
    LANG (unset)
    LANGUAGE (unset)
    LC_ALL=POSIX
    LD_LIBRARY_PATH=/home/abigail/Lib:/usr/local/lib:/usr/lib:/lib:/usr/X11R6/li
b:/opt/gnome/lib
    LOGDIR (unset)
    PATH=/home/abigail/Bin:/opt/perl/bin:/usr/local/bin:/usr/local/X11/bin:/usr/
bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/games:/opt/povray/b
in:/opt/gnome/bin:/opt/opera/bin:/usr/share/texmf/bin:/opt/Acrobat4/bin:/opt/jav
a/blackdown/j2sdk1.3.1/bin:/usr/local/games/bin:/opt/gnuplot/bin:/opt/mysql/bin
    PERL5LIB=/home/abigail/Perl:/home/abigail/Sybase
    PERLDIR=/opt/perl
    PERL_BADLANG (unset)
    SHELL=/usr/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2002

From @tamias

On Thu, Jul 11, 2002 at 09​:50​:28AM -0700, Abigail wrote​:

$ perl \-wle '/\(?\{1\}\)?/'

results in

Quantifier unexpected on zero\-length expression in regex;
marked by \<\-\- HERE in m/\(?\{1\}\)? \<\-\- HERE / at \-e line 1\.

While this is a useful (fatal) error for expressions without side-effects,
it's a nuisance for expressions with side-effects. And doing a (?{ })
without side-effects is kind of useless...

The Perl regex machine is a nice framework to do backtracking with. And
then it would be useful to be able to do​:

\(?\{ CODE \}\)?

There is a workaround of course​:

\(?&#8203;:\(?\{ CODE \}\)|\)

But (?{ }) always succeeds. The only way for (?{ }) to be backtracked is
for the surrounding regex to backtrack.

Ronald

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2002

From @vanstyn

Abigail <abigail@​foad.org> wrote​:
: $ perl -wle '/(?{1})?/'
:
:results in
:
: Quantifier unexpected on zero-length expression in regex;
: marked by <-- HERE in m/(?{1})? <-- HERE / at -e line 1.
:
:
:While this is a useful (fatal) error for expressions without side-effects,
:it's a nuisance for expressions with side-effects. And doing a (?{ })
:without side-effects is kind of useless...

Presumably the only relevant side-effects are the ones that occur under
backtracking, ie rollback of local()ised variables. If I understand you
correctly you want to be able to say​:
  local $count = 0;
  "foobar" =~ m{
  (?{ local $count = 1 })?
  foo
  (??{ $count ? 'baz' : 'bar' })
  };
... and have it match 'foobar' the second time through. Is that right?

Do you have a more concrete example that cannot easily be expressed
using the currently supported syntax?

What would you want m/(?{1})*/ to do? The same as C< 1 while 1 >?

:Flags​:
: category=core
: severity=medium

As far as I am aware we consciously chose to impose this restriction,
so I'd class this as a wishlist item rather than a bug. If the
restriction is underdocumented (which is quite likely), then
the docs need fixing.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2002

From @Abigail

On Thu, Jul 11, 2002 at 01​:10​:27PM -0400, Ronald J Kimball wrote​:

On Thu, Jul 11, 2002 at 09​:50​:28AM -0700, Abigail wrote​:

$ perl \-wle '/\(?\{1\}\)?/'

results in

Quantifier unexpected on zero\-length expression in regex;
marked by \<\-\- HERE in m/\(?\{1\}\)? \<\-\- HERE / at \-e line 1\.

While this is a useful (fatal) error for expressions without side-effects,
it's a nuisance for expressions with side-effects. And doing a (?{ })
without side-effects is kind of useless...

The Perl regex machine is a nice framework to do backtracking with. And
then it would be useful to be able to do​:

\(?\{ CODE \}\)?

There is a workaround of course​:

\(?&#8203;:\(?\{ CODE \}\)|\)

But (?{ }) always succeeds. The only way for (?{ }) to be backtracked is
for the surrounding regex to backtrack.

Well, yes. Consider the following code to generate all combinations
of a 4 element set​:

"" =~ /(?{ @​x = qw !A B C D!; @​y = (0) x 4; })
  (?​:(?{ local $y [0] = 1 })|)
  (?​:(?{ local $y [1] = 1 })|)
  (?​:(?{ local $y [2] = 1 })|)
  (?​:(?{ local $y [3] = 1 })|)
  (?(?{ print "@​x[grep {$y [$_]} 0 .. 3]\n" }) fail )/x;

I'd find it more logical to be able to write it as​:

"" =~ /(?{ @​x = qw !A B C D!; @​y = (0) x 4; })
  (?{ local $y [0] = 1 })?
  (?{ local $y [1] = 1 })?
  (?{ local $y [2] = 1 })?
  (?{ local $y [3] = 1 })?
  (?(?{ print "@​x[grep {$y [$_]} 0 .. 3]\n" }) fail )/x;

 
as '?' indicates "first try matching, then try without".
 
Abigail

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2002

From @Abigail

On Thu, Jul 11, 2002 at 06​:28​:02PM +0100, Hugo van der Sanden wrote​:

Abigail <abigail@​foad.org> wrote​:
: $ perl -wle '/(?{1})?/'
:
:results in
:
: Quantifier unexpected on zero-length expression in regex;
: marked by <-- HERE in m/(?{1})? <-- HERE / at -e line 1.
:
:
:While this is a useful (fatal) error for expressions without side-effects,
:it's a nuisance for expressions with side-effects. And doing a (?{ })
:without side-effects is kind of useless...

Presumably the only relevant side-effects are the ones that occur under
backtracking, ie rollback of local()ised variables. If I understand you
correctly you want to be able to say​:
local $count = 0;
"foobar" =~ m{
(?{ local $count = 1 })?
foo
(??{ $count ? 'baz' : 'bar' })
};
.. and have it match 'foobar' the second time through. Is that right?

Yes.

Do you have a more concrete example that cannot easily be expressed
using the currently supported syntax?

Well, as I said, there's a workaround, so it's always expressable in
the currently supported syntax. But expressing (?{ CODE }){100,200}
as a sequence of | clauses is a bit awkward.

What would you want m/(?{1})*/ to do? The same as C< 1 while 1 >?

Yes.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jul 11, 2002

From @vanstyn

Abigail <abigail@​foad.org> wrote​:
:On Thu, Jul 11, 2002 at 06​:28​:02PM +0100, Hugo van der Sanden wrote​:
:> Do you have a more concrete example that cannot easily be expressed
:> using the currently supported syntax?
:
:Well, as I said, there's a workaround, so it's always expressable in
:the currently supported syntax. But expressing (?{ CODE }){100,200}
:as a sequence of | clauses is a bit awkward.

Hence 'cannot _easily_ be expressed'.

:> What would you want m/(?{1})*/ to do? The same as C< 1 while 1 >?
:
:Yes.

I think this is in large part what the current behaviour aims to
guard against.

I could imagine supporting this in 5.10 by way of a new switch, but
I do not think it would be wise to change the default behaviour.
I would also be tempted to allow any such switch also to turn on
the currently disabled backtracking through assertions, which would
allow patterns such as /(?=.*(.))/ to backtrack and find alternate
ways of matching the assertion.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Jun 4, 2012

From @iabyn

removing this ticket from the (?{}) metabug, as its a wishlist rather
than a bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants