Могу ли я изменить сленг Perl 6 внутри метода?

Perl 6 Regex является более конкретным типом Method, поэтому у меня возникла идея, что, может быть, я смогу сделать что-нибудь магическое с помощью обычного метода, который производит то же самое. Мне особенно любопытно делать это без изменения грамматики.

Однако, глядя на Perl6 / Grammar.nqp ( что я почти не понимаю), что на самом деле это не наследство. Я думаю, основываясь на моем чтении, что грамматика Perl 6 переключает сленги (подязыки), когда видит один из деклараторов регулярных выражений. То есть другая грамматика анализирует внутренности regex { ... } и method {...}.

Итак, во-первых, правильно?

Затем, просто для смеха, я подумал, что, возможно, я мог бы быть внутри блока метода, но сказать ему, чтобы он использовал другой сленг (см., Например, " Сленги "из Адвент-календаря Perl 6 на 2013 год или "Сленг сегодня").

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

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

Практической пользы от этого у меня нет. Я просто все думаю об этом.


person brian d foy    schedule 05.07.2017    source источник
comment
Итак, во-первых, правильно ли (что) другая грамматика анализирует внутренности регулярного выражения {...} и метода {...} (?) Да, сленг / грамматика MAIN P6 анализирует тело объявления method, но использует Regex сленг / грамматика для анализа тела regex объявления.   -  person raiph    schedule 06.07.2017
comment
возможно, я мог бы быть внутри блока метода, но сказать ему, чтобы он использовал другой сленг. Вы могли бы, но использование сленга означает изменение грамматики (грамматики), которую использует компилятор, и вы написали, что не хотите изменять грамматику.   -  person raiph    schedule 06.07.2017
comment
Но могу ли я сказать ему, чтобы он использовал существующую грамматику, которая уже делает то, что я хочу?   -  person brian d foy    schedule 06.07.2017
comment
Я не понимаю, что вы хотите. (Вот почему я не пытался ответить. Ваш ответ на moritz оставил меня в еще большем замешательстве.) Некоторые предположения, чтобы попытаться закрепить то, что вы имеете в виду: 1) могу ли я подразумевать разумно; 2) это компилятор; 3) существующая грамматика является частью пары грамматика / действия, предназначенной для расширения / изгиба P6; 4) то, что вы хотите, - это то, что делает этот сленг; 5) вы готовы либо переключить сленг до того, как компиляция войдет в тело регулярного выражения, либо исправить ошибку после этого. Возможно, вы ответите да / нет на каждую из этих пяти догадок.   -  person raiph    schedule 06.07.2017
comment
@raiph Меня тоже немного смущает то, что я хочу, но кажется, что соответствующие термины перегружены, чтобы я не мог хорошо это выразить в данный момент.   -  person brian d foy    schedule 07.07.2017


Ответы (1)


Прежде всего, проектная документация Perl 6 требует наличия API, в котором регулярные выражения возвращают ленивый список возможных совпадений. Если бы Ракудо придерживался этого API, вы могли бы легко написать метод, который действовал бы как регулярное выражение, но синтаксический анализ был бы очень медленным (потому что ленивые списки, как правило, работают намного хуже, чем компактный список строковых позиций (целых чисел), которые действуют как стек с возвратом) ).

Вместо этого регулярные выражения Perl 6 возвращают совпадения. И вы можете сделать то же самое. Вот пример метода, который вызывается как регулярное выражение внутри грамматики:

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');

Метод rest реализует эквивалент регулярного выражения b.*. Надеюсь, это ответит на ваш вопрос.

Обновление: возможно, я неправильно понял вопрос. Если возникает вопрос «Как я могу создать объект регулярного выражения» (а не «как я могу написать код, который действует как регулярное выражение», как я понял), то ответ заключается в том, что вам нужно пройти через конструкцию цитирования rx//:

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

say 'fooabc' ~~ $re;       # Output: 「abc」
person moritz    schedule 06.07.2017
comment
Я не хочу соответствовать регулярному выражению, я хочу создать регулярное выражение. Я знаю, что мой вопрос требует некоторой доработки, потому что это шаткая идея, и весь язык, которым мы должны говорить о ней, подталкивает ее к другой интерпретации. - person brian d foy; 06.07.2017
comment
Вы можете создавать регулярные выражения с помощью оператора кавычек rx//. - person moritz; 07.07.2017