7

以下代码取自Perl 6 文档,在进行更多实验之前,我正在尝试更多地了解它:

proto token command {*}
      token command:sym<create>   { <sym> }
      token command:sym<retrieve> { <sym> }
      token command:sym<update>   { <sym> }
      token command:sym<delete>   { <sym> }
  1. 第一行中的那个是*随便的明星吗?可以是别的东西吗,比如

    proto token command { /give me an apple/ }
    
  2. “sym”可以是其他东西,例如

    command:eat<apple> { <eat> } ?
    
4

2 回答 2

9

{*}告诉运行时调用正确的候选者。
编译器允许您将{{*}}其缩短为{*}

这适用于所有proto例程,如submethodregextokenrule

regexproto 例程的情况下,只允许使用一个 bare {*}
主要原因可能是因为没有人真正想出一种让它在正则表达式子语言中合理工作的好方法。

所以这里有一个例子,proto sub它做了一些对所有候选人都通用的事情。

#! /usr/bin/env perl6
use v6.c;
for @*ARGS { $_ = '--stdin' when '-' }

# find out the number of bytes
proto sub MAIN (|) {
  try {
    # {*} calls the correct multi
    # then we get the number of elems from its result
    # and try to say it
    say {*}.elems #            <-------------
  }
  # if {*} returns a Failure note the error message to $*ERR
  or note $!.message;
}

#| the number of bytes on the clipboard
multi sub MAIN () {
  xclip
}

#| the number of bytes in a file
multi sub MAIN ( Str $filename ){
  $filename.IO.slurp(:!chomp,:bin)
}

#| the number of bytes from stdin
multi sub MAIN ( Bool :stdin($)! ){
  $*IN.slurp-rest(:bin)
}

sub xclip () {
  run( «xclip -o», :out )
  .out.slurp-rest( :bin, :close );
}
于 2017-02-17T15:17:15.403 回答
1

这回答了你的第二个问题。是的,已经很晚了。您必须区分两个不同sym的 s(或eats)。将标记定义为“副词”(或扩展语法标识符,无论您想如何称呼它)中的一个,以及标记本身上的那个。

如果您<eat>在令牌正文中使用,Perl 6 将根本找不到它。你会得到一个错误,比如

No such method 'eat' for invocant of type 'Foo'

Foo语法的名称在哪里。<sym>是一个预定义的记号,它与记号中的副词(或配对值)的值相匹配。

原则上,您可以使用扩展语法来定义多标记(或规则,或正则表达式)。但是,如果您尝试以这种方式定义它,您将得到一个不同的错误:

Can only use <sym> token in a proto regex

所以,你的第二个问题的答案是否定的。

于 2019-07-29T06:50:34.030 回答