gpt4 book ai didi

raku - 如何使 Perl 6 语法产生多个匹配(如 :ex and :ov)?

转载 作者:行者123 更新时间:2023-12-04 17:31:05 25 4
gpt4 key购买 nike

我要 grammar做这样的事情:

> "abc" ~~ m:ex/^ (\w ** 1..2) (\w ** 1..2) $ {say $0, $1}/
「ab」「c」
「a」「bc」

或者像这样:

> my regex left { \S ** 1..2  }
> my regex right { \S ** 1..2 }
> "abc" ~~ m:ex/^ <left><right> $ {say $<left>, $<right>}/
「ab」「c」
「a」「bc」

这是我的 grammar :

grammar LR {
regex TOP {
<left>
<right>
}
regex left {
\w ** 1..2
}
regex right {
\w ** 1..2
}
}

my $string = "abc";
my $match = LR.parse($string);
say "input: $string";
printf "split: %s|%s\n", ~$match<left>, ~$match<right>;

它的输出是:

$ input: abc
$ split: ab|c

所以, <left>只能贪得无厌 <right> .我应该如何修改代码以匹配两种可能的变体?

$ input: abc
$ split: a|bc, ab|c

最佳答案

Grammars are designed给出零个或一个答案,仅此而已,所以你必须使用一些技巧让他们做你想做的事。

Grammar.parse 只返回一个 Match对象,您必须使用不同的方法来获取所有匹配项:

sub callback($match) {
say $match;
}
grammar LR {
regex TOP {
<left>
<right>
$
{ callback($/) }
# make the match fail, thus forcing backtracking:
<!>
}
regex left {
\w ** 1..2
}
regex right {
\w ** 1..2
}
}

LR.parse('abc');

通过调用 <!> 使匹配失败断言(总是失败)迫使前面的原子回溯,从而找到不同的解决方案。当然,这会降低文法的可重用性,因为它在常规的文法调用约定之外工作。

请注意,对于调用者, LR.parse似乎总是失败;您将所有匹配项作为对回调函数的调用。

一个稍微好一点的 API(但下面的方法相同)是使用 gather/ take获取所有匹配项的序列:
grammar LR {
regex TOP {
<left>
<right>
$
{ take $/ }
# make the match fail, thus forcing backtracking:
<!>
}
regex left {
\w ** 1..2
}
regex right {
\w ** 1..2
}
}

.say for gather LR.parse('abc');

关于raku - 如何使 Perl 6 语法产生多个匹配(如 :ex and :ov)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46897895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com