Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl6 Need help to understand more about proto regex/token/rule

Tags:

regex

proto

raku

The following code is taken from the Perl 6 documentation, and I am trying to learn more about it before more experimentation:

proto token command {*}
      token command:sym<create>   { <sym> }
      token command:sym<retrieve> { <sym> }
      token command:sym<update>   { <sym> }
      token command:sym<delete>   { <sym> }
  1. Is the * in the first line a whatever-star? Can it be something else, such as

    proto token command { /give me an apple/ }
    
  2. Can "sym" be something else, such as

    command:eat<apple> { <eat> } ?
    
like image 773
lisprogtor Avatar asked Feb 17 '17 07:02

lisprogtor


2 Answers

{*} tells the runtime to call the correct candidate.
Rather than force you to write {{*}} for the common case of just call the correct one, the compiler allows you to shorten it to just {*}

That is the case for all proto routines like sub, method, regex, token, and rule.

In the case of the regex proto routines, only a bare {*} is allowed.
The main reason is probably because no-one has really come up with a good way to make it work sensibly in the regex sub-language.

So here is an example of a proto sub that does some things that are common to all of the candidates.

#! /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 );
}
like image 106
Brad Gilbert Avatar answered Nov 20 '22 21:11

Brad Gilbert


This answers your second question. Yes, it's late. You have to distinguish two different syms (or eats). The one that's on the definition of the token as an "adverb" (or extended syntax identifier, whatever you want to call it), and the one that's on the token itself.

If you use <eat> in the token body, Perl 6 will simply not find it. You will get an error like

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

Where Foo would be the name of the grammar. <sym> is a predefined token, which matches the value of the adverb (or pair value) in the token.

You could, in principle, use the extended syntax to define a multi token (or rule, or regex). However, if you try to define it in this way, you will get a different error:

Can only use <sym> token in a proto regex

So, the answer to your second question is no, and no.

like image 41
jjmerelo Avatar answered Nov 20 '22 19:11

jjmerelo