grammar - Perl6 语法 : match full line

标签 grammar raku

我刚刚开始探索 perl6 语法。我怎样才能组成一个标记“行”来匹配行的开头和结尾之间的所有内容?我尝试了以下但没有成功:

my $txt = q:to/EOS/;
    row 1
    row 2
    row 3
    EOS


grammar sample {
    token TOP {
        <line>
    }

    token line {
        ^^.*$$
    }
}

my $match = sample.parse($txt);

say $match<line>[0];

最佳答案

我可以在您的语法中看到 2 个问题,这里的第一个是标记行,^^ 和 $$ 是行首和行尾的 anchor ,但是您可以在两者之间添加新行。为了说明,让我们使用一个简单的正则表达式,先不使用语法:

my $txt = q:to/EOS/;
    row 1
    row 2
    row 3
    EOS

if $txt ~~ m/^^.*$$/ {
    say "match";
    say $/;
}

运行它,输出是:
match
「row 1
row 2
row 3」

您会看到正则表达式匹配的更多,但是第一个问题不存在,这是因为棘轮,与 token 匹配将不起作用:
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";
}

运行它,输出是:
match regex
「row 1
row 2
row 3」
does not match token

我不太确定为什么,但 token 和 anchor $$ 似乎不能很好地协同工作。但是您想要的是搜索除换行符之外的所有内容,即\N*
以下语法主要解决您的问题:
grammar sample {
    token TOP {<line>}
    token line {\N+}
}

但是它只匹配第一次出现,当您只搜索一行时,您可能想要做的是搜索一行 + 一个可选的垂直空格(在您的情况下,您的字符串末尾有一个新行,但是我猜你想取最后一行,即使最后没有新行),重复几次:
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;
}

该脚本的输出开始:
「row 1」
「row 2」
「row 3」

为了帮助您使用和调试 Grammar,还有 2 个非常有用的模块:Grammar::Tracer 和 Grammar::Debugger。只需将它们包含在脚本的开头即可。 Tracer 显示由您的语法完成的匹配的彩色树。调试器允许您实时查看它的匹配步骤。

关于grammar - Perl6 语法 : match full line,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34506093/

相关文章:

regex - 将奇数和偶数正则表达式结合到正则语法中?

parsing - 解析器表达式语法 - 如何匹配不包括单个字符的任何字符串?

java - 任何适用于 Java 的 L(AL)R 语法

parsing - 可以使用 ANTLR 生成 CSP(通信顺序进程)解析器吗?

raku - 如何死于未定义的值?

read-eval-print-loop - perl6/raku 有 REPL shell 吗?

raku - Raku 中的有理数

grammar - 确定是否可以在 CFG 中模糊地派生字符串

traits - 移相器特性何时运行?

java - 如何从 Java 调用 Perl 6?