← All programs · Grammars and match trees
Grammars and match trees #18
Rakudo 2026.08 runs this program cleanly; the lines marked ≠ below are where the answers part. A difference is a lead, not a verdict: sometimes both are valid Raku, and sometimes Rakudo is the one that is wrong. This difference is preserved as a Rakumap finding ↗
The program
The grammar and its inputs come first. rm-dump, the same in every program of this topic, prints one line for every field of every node of the resulting Match — its text, position, .orig, .prematch, .made, its captures — so a difference in the shape of the match shows as a difference in output.
my token r0 { \w }
my token r1 { $<k0>=[ \w ] <&r0> }
my rule r2 { <r0> }
sub rm-q($v) { $v.defined ?? $v.raku !! 'Nil' }
sub rm-dump($m, Str $p) {
unless $m.defined { say "$p kind Nil"; return }
if $m ~~ Match {
say "$p kind Match";
say "$p str {$m.Str.raku}";
say "$p from {$m.from}";
say "$p to {$m.to}";
say "$p orig {rm-q($m.orig)}";
say "$p target {rm-q($m.target)}";
say "$p pre {rm-q($m.prematch)}";
say "$p post {rm-q($m.postmatch)}";
say "$p made {rm-q($m.made)}";
for $m.list.kv -> $i, $c { rm-dump($c, $p ~ '[' ~ $i ~ ']') }
for $m.hash.keys.sort -> $k { rm-dump($m.hash{$k}, $p ~ '<' ~ $k ~ '>') }
# Captures that start at the same position have no specified order
# (rakupp's varies from run to run), so ties are ordered by name.
say "$p caps {$m.caps.sort({ .value.from, ~.key }).map({ .key ~ '=' ~ .value.Str.raku }).join(' ')}";
}
elsif $m ~~ Positional {
say "$p kind List({$m.elems})";
for $m.list.kv -> $i, $c { rm-dump($c, $p ~ '.' ~ $i) }
}
else { say "$p kind {$m.^name}" }
}
my @inputs = "0", "1_", "";
for @inputs.kv -> $i, $in {
say "#$i input {$in.raku}";
if $in ~~ / :ratchet ( ( $<k0>=[ <k1=&r2> ] ) ) / { rm-dump($/, '@' ~ $i) }
else { say '@' ~ $i ~ ' kind Nil' }
}
Run executes the program in your browser, with the Raku++ build this site ships. Edit it and try variations.
What each compiler printed
| Rakudo 2026.08 | Raku++ 4.0.1 | |
|---|---|---|
input "0" | ||
$/ kind | Match | Match |
$/ str | "0" | "0" |
$/ from | 0 | 0 |
$/ to | 1 | 1 |
$/ orig | "0" | "0" |
$/ target | "0" | "0" |
$/ pre | "" | "" |
$/ post | "" | "" |
$/ made | Nil | Nil |
$/[0] kind | Match | Match |
$/[0] str | "0" | "0" |
$/[0] from | 0 | 0 |
$/[0] to | 1 | 1 |
$/[0] orig | "0" | "0" |
$/[0] target | "0" | "0" |
$/[0] pre | "" | "" |
$/[0] post | "" | "" |
$/[0] made | Nil | Nil |
$/[0][0] kind | Match | Match |
$/[0][0] str | "0" | "0" |
$/[0][0] from | 0 | 0 |
$/[0][0] to | 1 | 1 |
$/[0][0] orig | "0" | "0" |
$/[0][0] target | "0" | "0" |
$/[0][0] pre | "" | "" |
$/[0][0] post | "" | "" |
$/[0][0] made | Nil | Nil |
$/[0][0]<k0> kind | Match | Match |
$/[0][0]<k0> str | "0" | "0" |
$/[0][0]<k0> from | 0 | 0 |
$/[0][0]<k0> to | 1 | 1 |
$/[0][0]<k0> orig | "0" | "0" |
$/[0][0]<k0> target | "0" | "0" |
$/[0][0]<k0> pre | "" | "" |
$/[0][0]<k0> post | "" | "" |
$/[0][0]<k0> made | Nil | Nil |
$/[0][0]<k0> caps | | r0="0" ≠ |
$/[0][0]<k1> kind | Match | Match |
$/[0][0]<k1> str | "0" | "0" |
$/[0][0]<k1> from | 0 | 0 |
$/[0][0]<k1> to | 1 | 1 |
$/[0][0]<k1> orig | "0" | "0" |
$/[0][0]<k1> target | "0" | "0" |
$/[0][0]<k1> pre | "" | "" |
$/[0][0]<k1> post | "" | "" |
$/[0][0]<k1> made | Nil | Nil |
$/[0][0]<k1><r0> kind | Match | Match |
$/[0][0]<k1><r0> str | "0" | "0" |
$/[0][0]<k1><r0> from | 0 | 0 |
$/[0][0]<k1><r0> to | 1 | 1 |
$/[0][0]<k1><r0> orig | "0" | "0" |
$/[0][0]<k1><r0> target | "0" | "0" |
$/[0][0]<k1><r0> pre | "" | "" |
$/[0][0]<k1><r0> post | "" | "" |
$/[0][0]<k1><r0> made | Nil | Nil |
$/[0][0]<k1><r0> caps | | |
$/[0][0]<k1> caps | r0="0" | r0="0" |
$/[0][0] caps | k0="0" k1="0" | k0="0" k1="0" |
$/[0] caps | 0="0" | 0="0" |
$/ caps | 0="0" | 0="0" |
input "1_" | ||
$/ kind | Match | Match |
$/ str | "_" | "_" |
$/ from | 1 | 1 |
$/ to | 2 | 2 |
$/ orig | "1_" | "1_" |
$/ target | "1_" | "1_" |
$/ pre | "1" | "1" |
$/ post | "" | "" |
$/ made | Nil | Nil |
$/[0] kind | Match | Match |
$/[0] str | "_" | "_" |
$/[0] from | 1 | 1 |
$/[0] to | 2 | 2 |
$/[0] orig | "1_" | "1_" |
$/[0] target | "1_" | "1_" |
$/[0] pre | "1" | "1" |
$/[0] post | "" | "" |
$/[0] made | Nil | Nil |
$/[0][0] kind | Match | Match |
$/[0][0] str | "_" | "_" |
$/[0][0] from | 1 | 1 |
$/[0][0] to | 2 | 2 |
$/[0][0] orig | "1_" | "1_" |
$/[0][0] target | "1_" | "1_" |
$/[0][0] pre | "1" | "1" |
$/[0][0] post | "" | "" |
$/[0][0] made | Nil | Nil |
$/[0][0]<k0> kind | Match | Match |
$/[0][0]<k0> str | "_" | "_" |
$/[0][0]<k0> from | 1 | 1 |
$/[0][0]<k0> to | 2 | 2 |
$/[0][0]<k0> orig | "1_" | "1_" |
$/[0][0]<k0> target | "1_" | "1_" |
$/[0][0]<k0> pre | "1" | "1" |
$/[0][0]<k0> post | "" | "" |
$/[0][0]<k0> made | Nil | Nil |
$/[0][0]<k0> caps | | r0="_" ≠ |
$/[0][0]<k1> kind | Match | Match |
$/[0][0]<k1> str | "_" | "_" |
$/[0][0]<k1> from | 1 | 1 |
$/[0][0]<k1> to | 2 | 2 |
$/[0][0]<k1> orig | "1_" | "1_" |
$/[0][0]<k1> target | "1_" | "1_" |
$/[0][0]<k1> pre | "1" | "1" |
$/[0][0]<k1> post | "" | "" |
$/[0][0]<k1> made | Nil | Nil |
$/[0][0]<k1><r0> kind | Match | Match |
$/[0][0]<k1><r0> str | "_" | "_" |
$/[0][0]<k1><r0> from | 1 | 1 |
$/[0][0]<k1><r0> to | 2 | 2 |
$/[0][0]<k1><r0> orig | "1_" | "1_" |
$/[0][0]<k1><r0> target | "1_" | "1_" |
$/[0][0]<k1><r0> pre | "1" | "1" |
$/[0][0]<k1><r0> post | "" | "" |
$/[0][0]<k1><r0> made | Nil | Nil |
$/[0][0]<k1><r0> caps | | |
$/[0][0]<k1> caps | r0="_" | r0="_" |
$/[0][0] caps | k0="_" k1="_" | k0="_" k1="_" |
$/[0] caps | 0="_" | 0="_" |
$/ caps | 0="_" | 0="_" |
input "" | ||
$/ kind | Nil | Nil |
$/[0][0]<k0><r0> kind | — | Match ≠ |
$/[0][0]<k0><r0> str | — | "0" ≠ |
$/[0][0]<k0><r0> from | — | 0 ≠ |
$/[0][0]<k0><r0> to | — | 1 ≠ |
$/[0][0]<k0><r0> orig | — | "0" ≠ |
$/[0][0]<k0><r0> target | — | "0" ≠ |
$/[0][0]<k0><r0> pre | — | "" ≠ |
$/[0][0]<k0><r0> post | — | "" ≠ |
$/[0][0]<k0><r0> made | — | Nil ≠ |
$/[0][0]<k0><r0> caps | — | ≠ |
$/[0][0]<k0><r0> kind | — | Match ≠ |
$/[0][0]<k0><r0> str | — | "_" ≠ |
$/[0][0]<k0><r0> from | — | 1 ≠ |
$/[0][0]<k0><r0> to | — | 2 ≠ |
$/[0][0]<k0><r0> orig | — | "1_" ≠ |
$/[0][0]<k0><r0> target | — | "1_" ≠ |
$/[0][0]<k0><r0> pre | — | "1" ≠ |
$/[0][0]<k0><r0> post | — | "" ≠ |
$/[0][0]<k0><r0> made | — | Nil ≠ |
$/[0][0]<k0><r0> caps | — | ≠ |
grammars-v1 · seed 1082 · recorded 2026-09-23 with Rakudo 2026.08 and Raku++ 4.0.1-132-g3e242220-modified · Source on GitHub ↗