如何在语法中引用先前匹配的项目?

Håk*_*and 3 grammar raku

我正在尝试解析 BibTeX 作者字段,并将其拆分为单独的作者。这将帮助我重写每个作者的姓名首字母。这是一个最小的例子:

use v6;

my $str = '{Rockhold, Mark L and Yarwood, RR and Selker, John S}';

grammar BibTexAuthor {
    token TOP {
        <all-text> 
    }
    token all-text {
        '{' <authors> '}' 
    }
    token authors { 
        [<author> [' and ' || <?before '}'>]]+
    }
    token author {
        [<-[\s}]> || [' ' <!before 'and '>]]+
    }
}

class BibTexAuthor-actions {
    method TOP($/) {
        say $/;
        print "First author = ";
        say $<author>.made[0];
        make $/.Str;
    }
    method all-text($/) {
        make $/.Str;
    }
    method authors($/) {
        make $/.Str;
    }
    method author($/) {
        make $/.Str;
    }
}
my $res = BibTexAuthor.parse( $str, actions => BibTexAuthor-actions.new).made;
Run Code Online (Sandbox Code Playgroud)

输出

?{Rockhold, Mark L and Yarwood, RR and Selker, John S}?
 all-text => ?{Rockhold, Mark L and Yarwood, RR and Selker, John S}?
  authors => ?Rockhold, Mark L and Yarwood, RR and Selker, John S?
   author => ?Rockhold, Mark L?
   author => ?Yarwood, RR?
   author => ?Selker, John S?
First author = Nil
Run Code Online (Sandbox Code Playgroud)

为什么我无法提取方法中的第一作者TOP

mor*_*itz 5

为什么我无法提取方法中的第一作者TOP

因为您并没有真正在操作方法中提取任何数据。您所做的只是将匹配的字符串附加到$/.made,这实际上并不是您最终想要的数据。

如果你想最终有单独的作者,你应该makeauthorsaction 方法中设置一个作者数组。例如:

use v6;

my $str = '{Rockhold, Mark L and Yarwood, RR and Selker, John S}';

grammar BibTexAuthor {
    token TOP {
        <all-text> 
    }
    token all-text {
        '{' <authors> '}' 
    }
    token authors { 
        [<author> [' and ' || <?before '}'>]]+
    }
    token author {
        [<-[\s}]> || [' ' <!before 'and '>]]+
    }
}

class BibTexAuthor-actions {
    method TOP($/) {
        make { authors => $<all-text>.made };
    }
    method all-text($/) {
        make $/<authors>.made;
    }
    method authors($/) {
        make $/<author>».made;
    }
    method author($/) {
        make $/.Str;
    }
}
my $res = BibTexAuthor.parse( $str, actions => BibTexAuthor-actions.new).made;

say $res.perl;
Run Code Online (Sandbox Code Playgroud)

印刷

${:authors($["Rockhold, Mark L", "Yarwood, RR", "Selker, John S"])}
Run Code Online (Sandbox Code Playgroud)

所以现在.made顶级匹配的 是一个散列,其中authors键保存一个数组。如果你想访问第一作者,你现在可以说

say $res<authors>[0];
Run Code Online (Sandbox Code Playgroud)

要得到 Rockhold, Mark L