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

How to refer to previously matched items in a grammar?

我正在尝试解析 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;

输出:

「{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

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

$<all-text><authors><author>[0];

请注意,直到现在我都不知道语法是如何工作的。我正在像你一样学习语言。

但只要查看数据结构,就很容易意识到它是一棵树,以及您要查找的值在该树中的哪个位置。

你可以通过说

输出任何数据结构
dd $someStructure;
say $someStructure.perl;

如果您发现它不可读,您可以尝试 Dumper Modules

Why am I not able to extract the first author in the TOP method?

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

如果你想在最后有不同的作者,你应该在 authors 操作方法中 make 一组作者。例如:

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;

打印

${:authors($["Rockhold, Mark L", "Yarwood, RR", "Selker, John S"])}

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

say $res<authors>[0];

得到Rockhold, Mark L