regex - 结合状态和令牌抛出。为什么?
问题描述
这有效
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 时效率很低。因此,如果这是真正的代码而不是挑战条目,我必须将令牌(文件)设为全局。
为什么会发生这种情况?
解决方案
TL;DR我喜欢取0。有一种解决方法(请参阅 take 1),但我认为这不值得。我不认为平原效率低下my
(见 take 2)。我认为state
应该在编译时拒绝使用正则表达式/方法(参见 take 3和5)或保持原样(参见 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”。有人故意犯state
了sub
一个编译时错误,而延续的概念将是一个真正巨大的项目,所以我认为在接下来的几年里,如果有的话,合适的事情是state
在一个方法或规则上也做出一个编译时错误。
或者,也许更合适的是,现在这已经被 SO 覆盖了,有一个记录在案的替代方案(语法)和解决方法(采取 1),现在是进入下一个级别的时候了......
脚注
1请参阅我对...正则表达式范围中的差异的回答。声明的正则表达式的行为state
似乎没有遵循我在该答案中引用的设计推测的直接阅读。至少我从那个答案的叙述中的以下一点也是错误的......
"
<bar>
如上所述。它优先解析为名为my
.our
&bar
...因为在此答案的 take 1 代码中,正则表达式调用必须以 an 为前缀&
才能工作。也许他们的工作完全是偶然的。