为什么在Perl 6语法原型中没有任何内容?

use*_*601 8 regex grammar perl6 raku

声明原型时,可以在多方法/子代码周围附加其他代码。举一个愚蠢的例子:

proto sub foo(|) { 'Camelia says “' ~ {*} ~ '!”' }
multi sub foo(1) { "hi"  }
multi sub foo($) { "bye" }

say foo(1) # Camelia says “hi!”
Run Code Online (Sandbox Code Playgroud)

我还没有遇到任何时间(还)在那里我已经感到的巨大有用的,但在另一面,我已经在那里正则表达式中遇到一些/语法的世界里,我偶尔发现自己重复自己在所有的原令牌-这并不是说我不能转移到单独的令牌中,而是增加了层次结构和操作的额外层。比较假设

grammar Bar { 
   token TOP { <meta>* }
   token metastart { '#' }
   proto token meta { <metastart> {*} }
         token meta:name { ( \w* ) }
         token meta:date { (\d**6) }
}
Run Code Online (Sandbox Code Playgroud)

在那里他们只是操作方法除了需要TOPmeta:namemeta:date

grammar Bar { 
   token TOP { <meta>* }
   token metastart { '#' }
   token meta { <metastart> <metacontent> }

   proto token metacontent      {   *   }
         token metacontent:name {  \w*  }
         token metacontent:date { \d**6 }
}
Run Code Online (Sandbox Code Playgroud)

现在metacontent:name,这需要三种方法:metacontent:date和,然后是一个相当多余的对象meta,整个身体将是make $<metacontent>.made

尽管我已经看到文档/注释四处徘徊,说可以在语法内部的原型中投入代码,但如果将任何东西放置在原型令牌/正则表达式/规则的主体中,而不是单个*,则编译器会抱怨:Proto regex body must be {*} (or <*> or <...>, which are deprecated)

这是尚未实现的功能,还是计划不再允许原型中的任何内容?如果是后者,为什么proto还需要指定者?(我猜这是因为原型令牌/正则表达式/规则的分配有一些特殊之处,因为在语法内部删除原型会导致运行时失败,这与sub / method世界不同。

jjm*_*elo 1

事实上,原始正则表达式只不过是多个标记的分组设备。文档说:

我们将创建的一组值的名称

他们并没有真正声明一个例程 multi,事实上,该原型后面的标记并没有声明为 multi,它们只是具有有趣名称的标记(它们是正则表达式,它们是方法)。

在您的情况下,您可以通过使用交替来简单地避免额外的原型标记,这实际上就是语法中原型的含义:

grammar Bar { 
    token TOP { <meta>* }
    token metastart { '#' }
    token meta { <metastart> [ <name> | <date> ] }
    token name {  \w*  }
    token date { \d**6 }
}

say Bar.parse( "#Hey" );
say Bar.parse( "#3333" );
Run Code Online (Sandbox Code Playgroud)