Here I see problem 2 in your grammar, the first of which is the line of tokens, ^^ and $$ are anchors for the beginning and end of the line, and you can have a new line between them. To illustrate this, simply use a simple regular expression without the first grammar:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS if $txt ~~ m/^^.*$$/ { say "match"; say $/; }
By running this, the output will be:
match 「row 1 row 2 row 3」
You see that the regular expression matches the desired one more, however, the first problem does not exist, this is due to ratcheting, matching with the token will not work:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS my regex r {^^.*$$}; if $txt ~~ &r { say "match regex"; say $/; } else { say "does not match regex"; } my token t {^^.*$$}; if $txt ~~ &t { say "match token"; say $/; } else { say "does not match token"; }
By running this, the output will be:
match regex 「row 1 row 2 row 3」 does not match token
I'm not quite sure why, but the $$ token and anchor don't seem to work together. But instead, you are looking for everything except a new line, which is \ N * The following grammar solves mainly your problem:
grammar sample { token TOP {<line>} token line {\N+} }
However, it matches only the first, since you are looking for only one line, what you might want is a line search + optional vertical space (in your case, you have a new line at the end of your string, but I think you would like to take the last line, even if there is no new line at the end), is repeated several times:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS grammar sample { token TOP {[<line>\v?]*} token line {\N+} } my $match = sample.parse($txt); for $match<line> -> $l { say $l; }
The output of this script begin:
「row 1」 「row 2」 「row 3」
Also, to help you use and debug your grammar, there are 2 really useful modules: Grammar :: Tracer and Grammar :: Debugger. Just include them at the beginning of the script. Tracer shows a colorful matching tree performed by your grammar. Debugger lets you see it in stages in real time.