Parsing 自定义解析返回值,保留未命名的终端

Parsing 自定义解析返回值,保留未命名的终端,parsing,grammar,raku,Parsing,Grammar,Raku,以语法为例: TOP ⩴ 'x' Y 'z' Y ⩴ 'y' 下面是如何使用各种解析器(不是手动编写的,而是从语法生成的)获取准确值[“TOP”,“x”,“Y”,“Y”],“z”]: xyz__Parse-Eyapp.eyp xyz__Regexp-Grammars.pl 如何从中获取值[“TOP”,“x”,“Y”,“Y”],“z”]?您不允许更改规则的形状,因为这可能会破坏用户附加的语义,否则任何其他内容都是公平的。我仍然认为解决方案的关键是match变量,但我不知道如何解决。不是完整的答

以语法为例:

TOP ⩴ 'x' Y 'z'
Y ⩴ 'y'
下面是如何使用各种解析器(不是手动编写的,而是从语法生成的)获取准确值
[“TOP”,“x”,“Y”,“Y”],“z”]

xyz__Parse-Eyapp.eyp


xyz__Regexp-Grammars.pl


如何从中获取值
[“TOP”,“x”,“Y”,“Y”],“z”]
?您不允许更改规则的形状,因为这可能会破坏用户附加的语义,否则任何其他内容都是公平的。我仍然认为解决方案的关键是match变量,但我不知道如何解决。

不是完整的答案,但提供了一些标记为捕获部分和非捕获部分的输入字符串

但是,它不能让您区分正则表达式中的非捕获文本和隐式匹配的空白

您可以通过添加位置捕捉并使用

除了缺少顶级
top
(只有在硬编码的情况下,您才有可能得到)之外,这与您想要的差不多

请注意,这并不包括所有边缘情况;例如,当捕获被量化时,
$p.value
是一个数组,而不是一个匹配对象,因此您需要在其中添加另一个级别的
.map
,但总体思路应该很清楚

%strict
%tree

%%
start:
    TOP { shift; use JSON::MaybeXS qw(encode_json); print encode_json $_[0] };
TOP:
    'x' Y 'z'   { shift; ['TOP', (scalar @_) ? @_ : undef] };
Y:
    'y' { shift; ['Y', (scalar @_) ? @_ : undef] };

%%
use 5.028;
use strictures;
use Regexp::Grammars;
use JSON::MaybeXS qw(encode_json);
print encode_json $/{TOP} if (do { local $/; readline; }) =~ qr{
<nocontext:>
<TOP>
<rule: TOP>
    <[anon=(x)]> <[anon=Y]> <[anon=(z)]>
    <MATCH=(?{['TOP', $MATCH{anon} ? $MATCH{anon}->@* : undef]})>
<rule: Y>
    <[anon=(y)]>
    <MATCH=(?{['Y', $MATCH{anon} ? $MATCH{anon}->@* : undef]})>

}msx;
grammar {rule TOP { x <Y> z }; rule Y { y };}.parse('x y z')
my $m = grammar {rule TOP { (x) <Y> (z) }; rule Y { (y) }}.parse('x y z');

sub transform(Pair $p) {
    given $p.key {
        when Int { $p.value.Str }
        when Str { ($p.key, $p.value.caps.map(&transform)).flat }
    }
}

say $m.caps.map(&transform);
(x (Y y) z)