我的语法在6.c(2018.01)中可以正常工作-我无法在6.d(2019.03.01)中获得稳定的输出。
当我打开Grammar :: Tracer(nice!)时,模式似乎是一致的。
但是使用相同的输入'm / s',我的输出会随机经过一系列结果,例如 ... * m / s = m.True * m / s = True.m * m / s = s-1.True * m / s = ms-1(这是我想要的那个,不在乎顺序)
我对unam =>?s有怀疑吗?// 是吗 匹配对象的内容(请参阅调试代码)-跟踪器在每个分支中仅显示一个unam匹配项。
欢迎所有建议!
#!/usr/bin/env perl6
sub get-dime( $dime-str ) {
use Grammar::Tracer;
my $unit-names = '|m|s';
grammar UnitGrammar {
token TOP { <dim> <divi> <den> }
token divi { \/ }
token dim { <unam> }
token den { <unam> }
token unam { <$unit-names> }
}
class UnitActions {
method TOP($/) { make $/.values.[0].made~'.'~$/.values.[1].made }
method dim($/) { make ~$<unam> }
method den($/) { make ~$<unam>~'-1' }
method divi($/) { make True }
}
my $match = UnitGrammar.parse($dime-str, :actions(UnitActions));
#[[ verbose for debug (also uncomment #use Grammar::Tracer)
say "$match=", $match.made;
say "--------------------";
say $match.values;
say $match.values.[0].made;
say $match.values.[1].made;
#]]
return $match.made if $match.so;
}
say $*PERL.compiler.version;
say get-dime( 'm/s' );
Run Code Online (Sandbox Code Playgroud)
rai*_*iph 10
@Håkon为游戏命名。您已准备好在跑道上着陆。我让我们靠近果岭,但在崎rough不平的地方。@ugexe抓住了球。@Håkon跳过了这个洞,移至下一个发球区域并打入一个洞。所以我想我要写赛后总结了。
这不是6.cVS 6.d。
潜在的问题是,哈希被指定为以随机顺序列出其键/值对。在较早的编译器中,哈希列表实现以固定顺序返回键/值对。然后,去年samcv为MoarVM实现了哈希随机化。它破坏了错误地依赖哈希顺序的代码。
因此,以下代码-自2018.05开始在Rakudo / MoarVM上-随机显示(a b)或(b a):
say .values given { apple => 'a', bananas => 'b' }
Run Code Online (Sandbox Code Playgroud)
您的代码正在调用.values一个Match对象。
调用该方法通常可以归结为以下效果:
say .values given ( apple => 'a', bananas => 'b', 0, 1, 2 ) .Capture
Run Code Online (Sandbox Code Playgroud)
将会显示一个列表,列表以0 1 2(它们是位置,因此它们以正确的顺序首先显示)开头,然后是a bor b a(它们的名称,因此它们以随机顺序显示最后一个)开头。
这又是因为a Match是的子类,Capture并且.values从该类继承其方法。正如其文档所说:
返回
Seq包含所有位置值,后跟所有命名参数值的。
您的代码中没有位置捕获。因此,您所看到的只是命名捕获的值。但是它们当然在列表中,因此出现在索引.[0],.[1]等下,这可能会诱使您认为它们是有序的(结合事实,在早期的Rakudos中,它们的随机顺序实际上是固定的)。
.caps对此进行了改进,因为它根据输入中的匹配位置对值进行排序。这将确保命名捕获的值列表的稳定排序-前提是所有捕获都不共享匹配的位置:
say .caps given 'foo' ~~ / $<alias>=<ident> /
Run Code Online (Sandbox Code Playgroud)
将随机显示(alias => ?foo? ident => ?foo?)或(ident => ?foo? alias => ?foo?)。
作为记录,这是此答案的第一个版本:
在这里,我想打高尔夫球的路要走得很远。
grammar {
token TOP { <one> <two> }
token one { 1 }
token two { 2 }
}.parse('12').values.say;
Run Code Online (Sandbox Code Playgroud)
在tio.run上运行的当前版本v2018.04中,此显示可靠(?1? ?2?)。在glot.io上运行的当前版本v2018.12中,这会生成或,(?1? ?2?)或者(?2? ?1?)在两者之间随机变化。
我不知道这是否是错误。调查仍在继续,但我认为我会将其发布为初步答案。
我不确定$/.values应该返回什么顺序(我得到了您所描述的随机顺序),而是使用了$/.values:
method TOP($/) {
make $<divi> ?? $/.values.[0].made~'.'~$/.values.[1].made
!! $/.values.[0].made
}
Run Code Online (Sandbox Code Playgroud)
您可以使用try $/.caps:
method TOP($/) {
make $<divi> ?? $/.caps.[0].value.made~'.'~$/.caps.[2].value.made
!! $/.caps.[0].value.made
}
Run Code Online (Sandbox Code Playgroud)
至少这对我有用。