UPD鉴于代码问题的出现没有提到空格,您不应该使用rule
完全构建。只需切换所有rule
s to token
s,你应该已经设置好了。一般来说,遵循布拉德的建议——使用token
除非你know你需要一个rule
(下面讨论)或regex
(如果您需要回溯)。
我最初的回答如下探讨了为什么rule
没用。我暂时把它留在里面。
TL;DR <garbchar> |
包含一个空格。直接跟在任何后面的空格atom https://en.wikipedia.org/wiki/Regular_expression#Syntax in a rule
表示标记化中断。您可以简单地删除这个不适当的空间,即写<garbchar>|
相反(或者更好的是,<.garbchar>|
如果你不需要捕获垃圾)来得到你想要的结果。
正如您最初的问题所允许的那样,这不是一个错误,只是您的思维模型关闭了。
您的回答正确地指出了问题:代币化 https://en.wikipedia.org/wiki/Lexical_analysis#Tokenization.
所以我们剩下的是你的后续问题,这是关于你的标记化的心理模型,或者至少是 Perl 6 默认情况下如何标记化:
为什么...我的第二个例子...连续两个 garbchars 出错:
'{<aa>}'
简单来说,问题是如何对其进行标记:
aa
简单的高级答案是,在解析白话时,aa
通常将被视为一个标记,而不是两个,并且默认情况下,Perl 6 采用这一普通定义。这就是您遇到的问题。
您可以推翻这个普通定义以获得您想要实现的任何标记化结果。但很少有必要这样做,而且在像这样的简单情况下当然也不需要这样做。
我将提供两条冗余路径,希望它们能引导人们找到正确的心智模型:
摘自维基百科页面关于标记化的“障碍”部分 https://en.wikipedia.org/wiki/Lexical_analysis#Obstacles,并将摘录与 P6 的具体讨论交织在一起:
通常,标记化发生在单词级别。然而,有时很难定义“词”的含义。分词器通常依赖于简单的启发式方法,例如:
- 标点符号和空格可能包含也可能不包含在生成的标记列表中。
在 Perl 6 中,您可以使用与标记化正交的捕获功能来控制解析树中包含或不包含的内容。
默认情况下,Perl 6 设计体现了这两种启发式的等效方法。
得到的关键是它是rule
处理一串标记(复数)的构造。这token
构造用于定义每次调用一个令牌.
我想我的回答就到这里结束了,因为它已经很长了。请使用评论来帮助我们改进这个答案。我希望到目前为止我所写的内容有所帮助。