我试图使用以下语法解析BibTeX作者字段:
use v6;
use Grammar::Tracer;
# Extract BibTeX author parts from string. The parts are separated
# by a comma and optional space around the comma
grammar Author {
token TOP {
<all-text>
}
token all-text {
[<author-part> [[\s* ',' \s*] || [\s* $]]]+
}
token author-part {
[<-[\s,]> || [\s* <!before ','>]]+
}
}
my $str = "Rockhold, Mark L";
my $result = Author.parse( $str );
say $result;
Run Code Online (Sandbox Code Playgroud)
输出:
TOP
| all-text
| | author-part
| | * MATCH "Rockhold"
| | author-part
Run Code Online (Sandbox Code Playgroud)
但程序挂起(我必须按CTRL-C)才能中止.我怀疑这个问题与负前瞻断言有关.我试图删除它,然后程序不再挂起,但后来我也无法提取"Mark L"内部空间的最后一部分.
请注意,出于调试目的,Author上面的语法是我实际程序中使用的语法的简化版本.
表达[\s* <!before ','>]可能没有任何进展.因为它在量词中,它将一次又一次地重试(但不会向前移动),导致观察到挂起.
这样的结构将可靠地悬挂在弦的末端; [\s* <!before ',' || $>]通过在字符串的末尾使前瞻失败来修复它(在字符串的末尾是一个不在a之前的有效方法,).
至少对于这个简单的例子,看起来整个author-part令牌可能只是<-[,]>+,但也许这对于真正的问题来说是过于简单化了.
瞥了一眼all-text,我还指出了%quantifier修饰符,它使得匹配逗号分隔(或任何分隔的,真正的)事物变得更容易.