Perl Regex vs. Raku Regex, Unterschiede im Motor?

9

Ich versuche, eine Regex-basierte Lösung für das Rucksackproblem von Perl auf Raku umzustellen. Details zu Perlmonks

Die Perl-Lösung erstellt diesen regulären Ausdruck:

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

was gegen abgeglichen wird vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Danach %+enthält der Match-Hash die Gegenstände, die in den Sack gelegt werden sollen.

Meine Raku-Konvertierung lautet:

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

was auch passt vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Das Match-Objekt $/enthält jedoch nichts Nützliches. Außerdem saysagen meine Debugs alle Null, also scheint die Rückreferenz an diesem Punkt nicht zu funktionieren?

Hier ist mein Testskript:

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
quelle
1
Zu Ihrer
Information

Antworten:

1

Diese Antwort deckt nur ab, was falsch läuft. Es wird keine Lösung angesprochen. Ich habe keine entsprechenden Fehler gemeldet. Ich habe noch nicht einmal nach Fehlerwarteschlangen gesucht, um festzustellen, ob ich Berichte finden kann, die einem oder beiden der beiden Probleme entsprechen, auf die ich gestoßen bin.

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

zeigt an:

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

Wenn wir uns zuerst auf den ersten Aufruf von konzentrieren debug(die Zeilen beginnen mit 1und enden bei rex-var => 「x」), können wir Folgendes sehen:

  • Während des Anrufs an debug: $<rex-var>ist etwas schief gegangen. Es wird berichtet, dass es den Wert hat Nil.

  • Wenn die Regex-Übereinstimmung abgeschlossen ist und wir zur Hauptzeile zurückkehren, say $/wird ein vollständiges und korrekt ausgefülltes Ergebnis gemeldet, das die rex-varbenannte Übereinstimmung enthält.

Um ein Gefühl dafür zu bekommen, was schief gelaufen ist, lesen Sie bitte den Großteil meiner Antwort auf eine andere SO-Frage . Sie können die Verwendung~ sicher überspringen . Die Fußnoten 1, 2 und 6 sind für Ihr Szenario wahrscheinlich ebenfalls völlig irrelevant.

Für das zweite Spiel sehen wir, dass nicht nur während des Anrufs $<rex-var>gemeldet wird , sondern auch die endgültige Übereinstimmungsvariable, wie in der Hauptzeile mit dem zweiten gemeldet , das Spiel fehlt . Und der einzige Unterschied besteht darin, dass der Regex innerhalb eines äußeren Regex aufgerufen wird .Nildebugsay $/rex-var$regex

Raiph
quelle