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)