3
votes

A Perl 6 Regex is a more specific type of Method, so I had the idea that maybe I could do something black-magicky in a regular method that produces the same thing. I particularly am curious about doing this without changing any grammars.

However, looking at Perl6/Grammar.nqp (which I barely understand), that this is really not an inheritance thing. I think, based on my reading, that the Perl 6 grammar switches slangs (sub languages) when it sees one of the regex declarators. That is, a different grammar parses the guts of regex { ... } and method {...}.

So, first, is that right?

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

However, everything I've found looks like it wants to change the grammar. Is there a way to do it without that and return a string that is treated as if it had come out of regex { ... }?

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

I don't have any practical use for this. I just keep wondering about it.

1
"So, first, is that right (that) a different grammar parses the guts of regex { ... } and method {...} (?)" Yes, the MAIN P6 slang/grammar parses the body of a method declaration but uses the Regex slang/grammar to parse the body of a regex declaration.raiph
"maybe I could be inside a method block but tell it to use a different slang" You could, but using a slang means changing the grammar(s) the compiler is using and you wrote that you don't want to change the grammar.raiph
But, could I tell it to use an existing grammar that already does what I want?brian d foy
I'm confused about what you want. (Which is why I didn't attempt an answer. Your response to moritz has left me more confused.) Some guesses to try nail down what you mean: 1) "could I" implies sanely; 2) "it" is the compiler; 3) the "existing grammar" is part of a grammar/actions pair designed to extend/bend P6; 4) what you want is what that slang does; 5) you're willing to either switch slang before compilation enters the regex body or fix up the ast afterwards. It might help if you said yes/no to each of these five guesses.raiph
@raiph I'm slightly confused by what I want too, but it seems that the appropriate terms are overloaded to prevent me from expressing it well at the moment.brian d foy

1 Answers

4
votes

First of all, the Perl 6 design documents mandate an API where regexes return a lazy list of possible matches. If Rakudo adhered to that API, you could easily write a method that acted as a regex, but parsing would be very slow (because lazy lists tend to perform much worse than a compact list of string positions (integers) that act as a backtracking stack).

Instead, Perl 6 regexes return matches. And you can do the same. Here is an example of a method that is called like a regex inside of 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');

Method rest implements the equivalent of the regex b.*. I hope this answers your question.

Update: I might have misunderstood the question. If the question is "How can I 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 have to go through the rx// quoting construct:

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

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