好吧,这要么是一个错误,要么我看起来像个十足的白痴,而且我使用的环视断言完全错误。我不关心后者,所以我们开始吧。
我正在测试这个语法:
our grammar HC2 {
token TOP { <line>+ }
token line { [ <header> \n | <not-header> \n ] }
token header { <header-start> <header-content> }
token not-header { \N* }
token header-start { <header-one> }
token header-one { <[#]> <![#]> } # note this negative lookahead here
token header-content { \N* }
}
Run Code Online (Sandbox Code Playgroud)
我想捕获一个只有一个#符号的 Markdown 标题,仅此而已。
这是 Grammar::Tracer/Debugger 的输出:
所以它会直接跳过<header-start>捕获。如果我删除<![#]>否定的前瞻断言,我会得到以下结果:
这是一个错误还是我出去吃午饭了?
作为文本:
TOP
>
| line
>
| | not-header
>
| | * MATCH "# Grandmother's for a Brighter Future"
>
| * MATCH "# Grandmother's for a Brighter Future\n"
>
| line
>
| | not-header
>
| | * MATCH ""
>
| * MATCH "\n"
>
| line
>
| | not-header
>
| | * MATCH "# Development site"
>
| * MATCH "# Development site\n"
>
| line
>
| | not-header
>
| | * MATCH "* The new site is up and running at example.com"
>
| * MATCH "* The new site is up and running at example.com\n"
>
| line
>
| | not-header
>
TOP
>
| line
>
| | header
>
| | | header-start
>
| | | | header-one
>
| | | | * MATCH "#"
>
| | | * MATCH "#"
>
| | | header-content
>
| | | * MATCH " Grandmother's for a Brighter Future"
>
| | * MATCH "# Grandmother's for a Brighter Future"
>
| * MATCH "# Grandmother's for a Brighter Future\n"
>
| line
>
| | not-header
>
| | * MATCH ""
>
| * MATCH "\n"
>
| line
>
| | header
>
| | | header-start
>
| | | | header-one
>
| | | | * MATCH "#"
>
| | | * MATCH "#"
Run Code Online (Sandbox Code Playgroud)
更新:如果我修改header-start为:
token header-one { <[#]> <-[#]> }
它符合预期。然而,这并没有回答为什么原始代码不匹配的问题。
好的,所以非技术性的答案是我做了一个错误的假设,即|角色的行为与 Perl 中的行为相同。它不是。在 Perl 中,正则表达式引擎尝试匹配字符左侧的模式|。如果失败,它将继续执行右侧的模式。
要获得“老式”Perl 行为,请使用||称为“Alternation”运算符的运算符:https://docs.raku.org/language/regexes#Alternation:_||
该|运算符称为“最长交替”运算符。请参阅https://docs.raku.org/language/regexes#Longest_alternation:_|
关于“最长交替”运算符如何工作的更详细、更技术性的讨论如下: https: //design.raku.org/S05.html#Longest-token_matching
尽管我已经||通过阅读文档意识到了它的存在,但我并没有仔细阅读它。我错误地认为 Raku 核心开发人员的行为会|像 Perl 中那样,这||是我稍后可以了解的一些很酷的新操作符。
大要点:努力揭示您所做的基本假设,并且在仔细阅读文档之前不要做出任何假设。