Perl regex vs Raku regex, différences dans le moteur?


9

J'essaie de convertir une solution basée sur regex pour le problème de sac à dos de Perl en raku. Détails sur Perlmonks

La solution Perl crée cette expression régulière:

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

qui se compare vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Après cela, le hachage de correspondance %+contient les éléments à mettre dans le sac.

Ma conversion en raku est:

$<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 || { "" } ]

qui correspond également vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Mais l'objet de $/correspondance ne contient rien d'utile. De plus, mon débogage saydit tous Nil, donc à ce stade, la référence arrière ne semble pas fonctionner?

Voici mon script de test:

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>/;

1
Pour info, les questions raku sont autorisées sur PerlMonks
ikegami

Réponses:


1

Cette réponse ne couvre que ce qui ne va pas. Il n'aborde pas de solution. Je n'ai pas déposé de bogues correspondants. Je n'ai même pas encore cherché dans les files d'attente de bogues pour voir si je peux trouver des rapports correspondant à l'un ou aux deux problèmes que j'ai rencontrés.

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 $/;

affiche:

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

En nous concentrant d'abord sur le premier appel de debug(les lignes commençant par 1et se terminant par rex-var => 「x」), nous pouvons voir que:

  • Quelque chose a mal tourné lors de l'appel à debug: $<rex-var>est signalé comme ayant la valeur Nil.

  • Lorsque la correspondance d'expressions régulières est terminée et que nous revenons à la ligne principale, le say $/signale un résultat complet et correctement rempli qui inclut la rex-varcorrespondance nommée.

Pour commencer à avoir une idée de ce qui ne va pas, pensez à lire l'essentiel de ma réponse à une autre question SO . Vous pouvez ignorer l' utilisation en~ toute sécurité . Les notes de bas de page 1, 2 et 6 sont également probablement sans rapport avec votre scénario.

Pour la deuxième correspondance, nous voyons que non seulement est $<rex-var>signalé comme étant Nilpendant l' debugappel, la variable de correspondance finale, telle que rapportée dans la ligne principale avec la seconde say $/, manque également la rex-varcorrespondance. Et la seule différence est que l'expression régulière $regexest appelé à partir à l' intérieur d' un regex extérieur.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.