我正在尝试使用以下语法来解析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;
输出:
TOP
| all-text
| | author-part
| | * MATCH "Rockhold"
| | author-part
但是这里程序挂起(我必须按CTRL-C)以中止。我怀疑问题与否定的前瞻性断言有关。我试图将其删除,然后程序不再挂起,但是我也无法用内部空间提取最后一部分"Mark L"
。
请注意,出于调试目的,上面的Author
语法是我的实际程序中使用的语法的简化版本。
表达式[\s* <!before ','>]
可能没有任何进展。由于它位于量词中,因此将一次又一次重试(但不会向前移动),从而导致挂起。
这样的构造将可靠地挂在字符串的末尾; [\s* <!before ',' || $>]
可以通过在字符串的末尾也使超前失败来解决此问题(位于字符串的末尾是一种有效的方法,可以使它不在,
之前)。
至少对于这个简单的示例,看起来整个author-part
令牌可能只是<-[,]>+
,但是对于减少了这个问题的实际问题,也许这过于简化了。
[浏览all-text
,我还要指出% quantifier modifier,它使匹配以逗号分隔(或实际上是任何分隔的东西)变得容易。