首页 > 解决方案 > 结合状态和令牌抛出。为什么?

问题描述

这有效

sub test-string( $string )
{
    my token opening-brace { \( };
    my token closing-brace { \) };
    my token balanced-braces { 
        ( <opening-brace>+ ) <closing-brace> ** { $0.chars } 
    };

    so $string ~~ /^ <balanced-braces> $/;
}

这个

sub test-string( $string )
{
    state token opening-brace { \( };
    state token closing-brace { \) };
    state token balanced-braces { 
        ( <opening-brace>+ ) <closing-brace> ** { $0.chars } 
    };

    so $string ~~ /^ <balanced-braces> $/;
}    

死于

No such method 'opening-brace' for invocant of type 'Match'
  in regex balanced-braces at ch-2.p6 line 13
  in sub test-string at ch-2.p6 line 17
  in block <unit> at ch-2.p6 line 23

token我更喜欢第二个版本,因为我相信第一个版本在每次调用函数时都必须设置 s 时效率很低。因此,如果这是真正的代码而不是挑战条目,我必须将令牌(文件)设为全局。

为什么会发生这种情况?

标签: regexraku

解决方案


TL;DR我喜欢0。有一种解决方法(请参阅 take 1),但我认为这不值得。我不认为平原效率低下my(见 take 2)。我认为state应该在编译时拒绝使用正则表达式/方法(参见 take 35)或保持原样(参见 take 4)。除非你是一个愿意说服 jnthn 的编码天才,Rakudo 应该开始大幅增加对延续的接触(参见第 5 条)。

为什么会发生这种情况?(取1)

如果你这样写,“这个”就不会:

sub test-string( $string )
{
    state &opening-brace = token { \( }
    state &closing-brace = token { \) }
    state &balanced-braces = token { 
        ( <&opening-brace>+ ) <&closing-brace> ** { $0.chars } 
    }

    so $string ~~ /^ <&balanced-braces> $/;
}   

&在 regex 调用中的需要让我有点惊讶。1

为什么会发生这种情况?(取2)

为什么会发生什么

我相信第一个版本在每次调用函数时都必须设置令牌时效率很低。

你所说的“相信”、“相当低效”和“设置代币”是什么意思?我希望正则表达式代码只编译一次(如果每次都编译我会感到震惊)但还没有分析验证。

这让我想到了一系列问题:

&opening-parens您是否只关心每次调用函数时重新创建 3 个 lexpad 条目(等;更一般地说,是正则表达式的数量)所花费的时间test-string

您是否真正分析过运行原始代码并发现重大问题?

您是否真正衡量过这一点,并发现它是实际项目中“关键 3%”的一部分?

为什么会发生这种情况?(取 3 个)

声明器对sstate做了一件合理的事情sub——它会产生一个编译时错误:

state sub foo {}    # Compile time error: "Cannot use 'state' with sub declaration"
state my sub foo {} # Compile time error: "Type 'my' is not declared"

但是使用一个方法(这是一个正则表达式),它可以编译但没有任何用处:

state method foo {} # Compiles, but I failed to find a way to access `foo`
state regex bar {.}  # Same

我查看了 Rakudo 的 GH 问题队列,但未能找到讨论类似上述最后两行代码的问题(与您的token情况基本相同)。也许人们没有注意到这一点,或者至少不觉得提交错误会有所帮助?

为什么会发生这种情况?(取4个)

因此,您将发布一个 SO 文档,该文档state regex应在编译时被拒绝或做一些有用的事情。@Scimon++ 将记录另一种看待事物的方式。还有我。

为什么会发生这种情况?(取 5 个)

<Your Compiler Code Goes Here>

因为Raku是我们的MMORPG。如果您希望看到state声明符在与例程声明一起使用时做一些有用的事情(大概它应该产生一个编译时错误,就像它目前对 a 所做的那样,或者在“作用域延续”sub的约束内做一些花哨的延续事情构建 Raku 的顶部),那么考虑到 Rakudo 编译器主要是用 Raku 编写的,那么这项工作可能只是一个“smop”。有人故意犯statesub一个编译时错误,而延续的概念将是一个真正巨大的项目,所以我认为在接下来的几年里,如果有的话,合适的事情是state在一个方法或规则上也做出一个编译时错误。

或者,也许更合适的是,现在这已经被 SO 覆盖了,有一个记录在案的替代方案(语法)和解决方法(采取 1),现在是进入下一个级别的时候了......

脚注

1请参阅我对...正则表达式范围中的差异的回答。声明的正则表达式的行为state似乎没有遵循我在该答案中引用的设计推测的直接阅读。至少我从那个答案的叙述中的以下一点也是错误的......

"<bar>如上所述。它优先解析为名为my.our&bar

...因为在此答案的 take 1 代码中,正则表达式调用必须以 an 为前缀&才能工作。也许他们的工作完全是偶然的。


推荐阅读