perl6 Нужна помощь, чтобы узнать больше о прото-регулярном выражении / токене / правиле

Следующий код взят из документации 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. Может ли "сим" быть чем-то другим, например

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

person lisprogtor    schedule 17.02.2017    source источник


Ответы (2)


{*} сообщает среде выполнения, чтобы она вызывала правильного кандидата.
Вместо того, чтобы заставлять вас писать {{*}} для общего случая, когда просто вызывается правильный кандидат, компилятор позволяет вам сократить его до {*}

Так обстоит дело со всеми proto подпрограммами, такими как sub, method, regex, token и rule.

В случае regex прото-подпрограмм разрешен только голый {*}.
Основная причина, вероятно, в том, что никто действительно не придумал хороший способ заставить его работать разумно на подъязыке регулярных выражений.

Итак, вот пример 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 );
}
person Brad Gilbert    schedule 17.02.2017

Это ответ на ваш второй вопрос. Да уже поздно. Вы должны различать два разных sym (или eat). Тот, который указан в определении токена как «наречие» (или идентификатор расширенного синтаксиса, как бы вы его ни называли), и тот, который находится на самом токене.

Если вы используете <eat> в теле токена, Perl 6 его просто не найдет. Вы получите сообщение об ошибке

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

Где Foo было бы названием грамматики. <sym> - предопределенный токен, который соответствует значению наречия (или парному значению) в токен.

В принципе, вы можете использовать расширенный синтаксис для определения мульти-токена (или правила, или регулярного выражения). Однако, если вы попытаетесь определить его таким образом, вы получите другую ошибку:

Can only use <sym> token in a proto regex

Итак, ответ на ваш второй вопрос - нет и нет.

person jjmerelo    schedule 29.07.2019
comment
Большое спасибо jjmerelo за вашу помощь !! - person lisprogtor; 29.07.2019