令牌和规则之间的真正区别是什么?

问题描述 投票:4回答:1

由于Raku内置的语法,我被Raku吸引住了,以为我会玩弄它并编写一个简单的电子邮件地址解析器,唯一的问题是:我无法使它正常工作。

[在尝试实际可行的东西之前,我尝试了无数次迭代,但我一直在努力理解原因。

归根结底是将token更改为rule

这是我的示例代码:

grammar Email {
  token TOP { <name> '@' [<subdomain> '.']* <domain> '.' <tld> }  
  token name { \w+ ['.' \w+]* }
  token domain { \w+ }
  token subdomain { \w+ }
  token tld { \w+ }
}
say Email.parse('[email protected]');

无效,它只打印Nil,但是

grammar Email {
  rule TOP { <name> '@' [<subdomain> '.']* <domain> '.' <tld> }  
  token name { \w+ ['.' \w+]* }
  token domain { \w+ }
  token subdomain { \w+ }
  token tld { \w+ }
}
say Email.parse('[email protected]');

does可以正常打印

[email protected]」
 name => 「foo.bar」
 subdomain => 「baz」
 domain => 「example」
 tld => 「com」

我所做的只是从token TOPrule TOP

从我可以从文档中得到的信息来看,这两个关键字之间的唯一区别是,空格在rule中很重要,但在token中却没有。如果是这样,第一个示例应该可以工作,因为我想忽略模式中各个部分之间的空白。

删除两部分之间的空格rule TOP { <name>'@'[<subdomain>'.']*<domain>'.'<tld> }将行为恢复为打印Nil

任何人都可以了解我在这里发生的事情吗?

EDIT:改为将TOP规则更改为regex,这允许回溯使其也起作用。

问题仍然存在,当rule { }(与regex {:ratchet :sigspace }相同)不匹配时,token { }(与regex {:ratchet }相同)如何匹配?

电子邮件地址中没有空格,因此,出于所有意图和目的,它应该立即失败

raku context-free-grammar
1个回答
0
投票

根据Raku docs

  • 令牌方法比正则表达式方法快,并且忽略空格。令牌方法不会回溯;他们在第一个可能的时候放弃了匹配。
  • 规则方法与令牌方法相同,除了空白不被忽略。

未被忽略意味着它们被视为语法,而不是字面匹配。他们实际上插入了<.ws>。有关更多信息,请参见sigspace

© www.soinside.com 2019 - 2024. All rights reserved.