TL;DR Use "multiple dispatch".[1,2] See @user0721090601's answer for a thorough explanation of why things are as they are. See @p6steve's for a really smart change to your grammar if you want your number syntax to match Raku's.
多调度解决方案
有没有解决的办法?
一种方法是切换到显式多重调度。
您目前有一个value
调用特定命名值变体的令牌:
token value { <strvalue> | <numvalue> }
将其替换为:
proto token value {*}
然后根据语法多重调度目标规则重命名被调用的令牌,因此语法变为:
grammar MyGrammar
{
rule TOP { <keyword> '=' <value> }
token keyword { \w+ }
proto token value {*}
token value:str { '"' <( <-["]>* )> '"' }
token value:num { '-'? \d+ [ '.' \d* ]? }
}
say MyGrammar.parse('foo = 42');
say MyGrammar.parse('bar = "Hello, World!"');
这显示:
「foo = 42」
keyword => 「foo」
value => 「42」
「bar = "Hello, World!"」
keyword => 「bar」
value => 「Hello, World!」
默认情况下,这不会捕获各个交替。我们可以坚持“多重调度”,但重新引入子捕获的命名:
grammar MyGrammar
{
rule TOP { <keyword> '=' <value> }
token keyword { \w+ }
proto token value { * }
token value:str { '"' <( $<strvalue>=(<-["]>*) )> '"' }
token value:num { $<numvalue>=('-'? \d+ [ '.' \d* ]?) }
}
say MyGrammar.parse('foo = 42');
say MyGrammar.parse('bar = "Hello, World!"');
显示:
「foo = 42」
keyword => 「foo」
value => 「42」
numvalue => 「42」
「bar = "Hello, World!"」
keyword => 「bar」
value => 「Hello, World!」
strvalue => 「Hello, World!」
惊喜
令我惊讶的是,引号包含在value
.
I too was initially surprised.[3]
但目前的行为对我来说至少在以下方面也有意义:
脚注
[1] Use of multiple dispatch[2] is a solution, but seems overly complex imo given the original problem. Perhaps there's a simpler solution. Perhaps someone will provide it in another answer to your question. If not, I would hope that we one day have at least one much simpler solution. However, I wouldn't be surprised if we don't get one for many years. We have the above solution, and there's plenty else to do.
[2] While you can declare, say, method value:foo { ... }
and write a method (provided each such method returns a match object), I don't think Rakudo uses the usual multiple method dispatch mechanism to dispatch to non-method rule alternations but instead uses an NFA https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton.
[3] Some might argue that it "should", "could", or "would" "be for the best" if Raku did as we expected. I find I think my best thoughts if I generally avoid [sh|c|w]oulding about bugs/features unless I'm willing to take any and all downsides that others raise into consideration and am willing to help do the work needed to get things done. So I'll just say that I'm currently seeing it as 10% bug, 90% feature, but "could" swing to 100% bug or 100% feature depending on whether I'd want that behaviour or not in a given scenario, and depending on what others think.