Raku:捕获标记的作用“更高"地消失了. [英] Raku: effect of capture markers is lost "higher up"

查看:81
本文介绍了Raku:捕获标记的作用“更高"地消失了.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下Raku脚本:

#!/usr/bin/env raku
use v6.d;

grammar MyGrammar
{
    rule TOP { <keyword> '=' <value> }
    token keyword { \w+ }
    token value { <strvalue> | <numvalue> }
    token strvalue { '"' <( <-["]>* )> '"' }
    token 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!」

对于第二项,请注意,strvalue包含不带引号的字符串值,这与捕获市场<( ... )>的意图相同. 但是,令我惊讶的是,value中包含了引号 .

For the second item, note that strvalue contains the string value without quotes, as intended with the capture markets <( ... )>. However, to my surprise, the quotes are included in value.

有没有办法解决这个问题?

Is there a way around this?

推荐答案

TL; DR 使用多个调度". [1,2] 有关问题原因的详尽解释,请参见@ user0721090601的答案.照原样.如果您希望数字语法与Raku的语法相匹配,请参阅@ p6steve的语法的真正明智的更改.

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.

有没有办法解决这个问题?

Is there a way around this?

一种方法是切换到显式多调度.

One way is to switch to explicit multiple dispatch.

您当前有一个value令牌,该令牌调用专门命名的值变量:

You currently have a value token which calls specifically named value variants:

    token value { <strvalue> | <numvalue> }

替换为:

    proto token value {*}

,然后根据语法多个调度目标规则重命名被调用的令牌,因此语法变为:

and then rename the called tokens according to grammar multiple dispatch targeting rules, so the grammar becomes:

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!」

默认情况下,这不会捕获各个替代项.我们可以坚持多次派遣".但重新引入子捕捉的命名:

This doesn't capture the individual alternations by default. We can stick with "multiple dispatch" but reintroduce naming of the sub-captures:

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中.

最初我也很惊讶. [3]

I too was initially surprised.[3]

但是目前的行为至少在以下几个方面对我来说很有意义:

But the current behaviour also makes sense to me in at least the following senses:

  • 在某些情况下,现有的行为是值得的;

  • The existing behaviour has merit in some circumstances;

如果我期望的话也就不足为奇了,我认为在其他情况下我可能会做得到;

It wouldn't be surprising if I was expecting it, which I think I might well have done in some other circumstances;

要想得到 想要的当前行为,要想像您(和我)最初期望的那样工作,要想知道如何获得当前行为并不容易;

It's not easy to see how one would get the current behaviour if it was wanted but instead worked as you (and I) initially expected;

有一个解决方案,如上所述.

There's a solution, as covered above.

[1] 使用多个调度 [2] a 解决方案,但考虑到原始问题,imo似乎过于复杂.也许有一个更简单的解决方案.也许有人会在您问题的另一个答案中提供它.如果没有,我希望我们有一天至少有一个简单得多的解决方案.但是,如果我们多年都没有,我不会感到惊讶.我们已经有了上述解决方案,还有很多事情要做.

[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] 在您可以声明例如method value:foo { ... }并编写一个方法时(前提是每个这样的方法都返回一个匹配对象) ),我认为Rakudo不使用常规的多方法分派机制来分派给非方法规则变更,而是使用

[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.

[3] 某些人可能会认为它应该",可能"或将要"使用. 追求最好"如果Raku做到了我们所期望的.我发现,如果我一般不回避关于错误/功能的[sh | c | w],除非我愿意将他人提出的所有缺点纳入考虑范围,并且 愿意考虑,否则我会认为我最好的想法.帮助完成工作所需的工作.因此,我只想说我目前将其视为10%的错误,90%的功能,但是可以"表示转变为100%错误或100%功能,具体取决于我在给定情况下是否想要该行为,并取决于其他人的想法.

[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.

这篇关于Raku:捕获标记的作用“更高"地消失了.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆