Can I change Perl 6 slang inside a method?

A Perl 6 Regex is a more specific type of Method , so I got the idea that maybe I could do something black-magical in a regular method that does the same thing. I am especially interested in doing this without changing any grammars.

However, looking at Perl6 / Grammar.nqp (which I barely understand) it is not actually inheritance. I think based on my reading that the Perl 6 grammar switches slangs (sublanguages) when it sees one of the regex declarations. That is, a different grammar analyzes guts regex { ... }

and method {...}

.

So first, is this correct?

Then, just for a chuckle, I thought that maybe I could be inside the method block, but tell it to use a different slang (see, for example, "Slangs" from the Perl 6 Coming Calendar 2013 or "Slang Today" ) ...

However, all I've found looks like it wants to change grammar. Is there a way to do this without this, and return a string that is treated as if it had exited regex { ... }

?

method actually-returns-a-regex {
     ...
     }

      

I have no practical use. I just think about it.

+3


source to share


1 answer


First of all, the Perl 6 design docs provide an API where regular expressions return a lazy list of possible matches. If Rakudo stuck with this API, you could easily write a method that acts like a regex, but parsing would be very slow (since lazy lists tend to be much worse than a compact list of string positions (integers) that act like freeze).

Instead, Perl 6 regular expressions return matches. And you can do the same. Below is an example of a method called regular expression within a grammar:

grammar Foo {
    token TOP { a <rest> }

    method rest() {
        if self.target.substr(self.pos, 1) eq 'b' {
            return Match.new(
                orig   => self.orig,
                target => self.target,
                from => self.pos,
                to   => self.target.chars,
            );
        }
        else {
            return Match.new();
        }
    }
}

say Foo.parse('abc');
say Foo.parse('axc');

      



The method rest

implements the equivalent of a regular expression b.*

. Hope this answers your question.

Update: I may have misunderstood the question. If the question arises, "How to create a regex object" (and not "how can I write code that acts like a regex" as I understood it), the answer is that you need to go through the quotes constructrx//

my $str = 'ab.*';
my $re = rx/ <$str> /;

say 'fooabc' ~~ $re;       # Output: 「abc」

      

+2


source







All Articles