Perl regex vs. Raku regex, ¿diferencias en el motor?

9

Estoy tratando de convertir una solución basada en expresiones regulares para el problema de la mochila de Perl a raku. Detalles sobre Perlmonks

La solución Perl crea esta expresión regular:

(?<P>(?:vvvvvvvvvv)?)
(?<B>(?:vv)?)
(?<Y>(?:vvvv)?)
(?<G>(?:vv)?)
(?<R>(?:v)?)
0
(?=
(?(?{ $1 })wwww|)
(?(?{ $2 })w|)
(?(?{ $3 })wwwwwwwwwwww|)
(?(?{ $4 })ww|)
(?(?{ $5 })w|)
)

que obtiene emparejado contra vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Después de eso, el hash de partido %+contiene los elementos para poner en el saco.

Mi conversión de raku es:

$<B> = [ [ vv ]? ]
$<P> = [ [ vvvvvvvvvv ]? ]
$<R> = [ [ v ]? ]
$<Y> = [ [ vvvv ]? ]
$<G> = [ [ vv ]? ]
0
<?before
[ { say "B"; say $/<B>; say $0; say $1; $1 } w || { "" } ]
[ { say "P"; say $/<P>; say $0; say $1; $2 } wwww || { "" } ]
[ { say "R"; say $/<R>; say $0; say $1; $3 } w || { "" } ]
[ { say "Y"; say $/<Y>; say $0; say $1; $4 } wwwwwwwwwwww || { "" } ]
[ { say "G"; say $/<G>; say $0; say $1; $5 } ww || { "" } ]

que también partidos vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Pero el objeto de coincidencia $/no contiene nada útil. Además, todos mis depuradores saydicen Nil, por lo que en ese momento la referencia no parece funcionar.

Aquí está mi script de prueba:

my $max-weight = 15;
my %items      =
    'R' => { w =>  1, v =>  1 },
    'B' => { w =>  1, v =>  2 },
    'G' => { w =>  2, v =>  2 },
    'Y' => { w => 12, v =>  4 },
    'P' => { w =>  4, v => 10 }
;

my $str = 'v' x  %items.map(*.value<v>).sum ~
          '0' ~
          'w' x  $max-weight;

say $str;

my $i = 0;
my $left = my $right = '';

for %items.keys -> $item-name
{
    my $v = 'v' x %items{ $item-name }<v>;
    my $w = 'w' x %items{ $item-name }<w>;

     $left  ~= sprintf( '$<%s> = [ [ %s ]? ] ' ~"\n", $item-name, $v );
     $right ~= sprintf( '[ { say "%s"; say $/<%s>; say $0; say $1; $%d } %s || { "" } ]' ~ "\n", $item-name, $item-name, ++$i, $w );
}
use MONKEY-SEE-NO-EVAL;

my $re = sprintf( '%s0' ~ "\n" ~ '<?before ' ~ "\n" ~ '%s>' ~ "\n", $left, $right );

say $re;
dd $/ if $str ~~ m:g/<$re>/;
Holli
fuente
1
Para su información, se permiten preguntas raku en PerlMonks
ikegami

Respuestas:

1

Esta respuesta solo cubre lo que va mal. No aborda una solución. No he presentado los errores correspondientes. Aún no he buscado colas de errores para ver si puedo encontrar informes correspondientes a cualquiera de los dos problemas que he surgido.

my $lex-var;

sub debug { .say for ++$, :$<rex-var>, :$lex-var }

my $regex = / $<rex-var> = (.) { $lex-var = $<rex-var> } <?before . { debug }> / ;

'xx' ~~   $regex;     say $/;
'xx' ~~ / $regex /;   say $/;

muestra:

1
rex-var => Nil
lex-var => x
x
 rex-var => x
2
rex-var => Nil
lex-var => x
x

Centrándonos primero en la primera llamada de debug(las líneas que comienzan 1y terminan en rex-var => 「x」), podemos ver que:

  • Algo salió mal durante la llamada a debug: $<rex-var>se informa que tiene el valor Nil.

  • Cuando finaliza la coincidencia de expresiones regulares y volvemos a la línea principal, say $/informa un resultado completo y correctamente poblado que incluye la rex-varcoincidencia nombrada.

Para comenzar a tener una idea de lo que salió mal, considere leer la mayor parte de mi respuesta a otra pregunta SO . Puede omitir el uso de~ forma segura . Las notas al pie 1,2 y 6 también son probablemente completamente irrelevantes para su escenario.

Para la segunda coincidencia, vemos que no solo se $<rex-var>informa como Nildurante la debugllamada, la variable de coincidencia final, como se informó en la línea principal con la segunda say $/, también falta la rex-varcoincidencia. Y la única diferencia es que la expresión regular $regexse llama desde dentro de una expresión regular exterior.

raiph
fuente