Как повторно использовать языковой токен в пользовательской грамматике (Raku) - PullRequest
6 голосов
/ 01 апреля 2020

Я хочу использовать token parameter из Perl6 :: Grammar в моем пользовательском сленге, чтобы добавить параметр "custom-param" без машины go culting .

Что я имею в виду:

my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');

role Nogil::NogilGrammar {
    token parameter { # the new one
        "custom-param" || < here the token stolen from $main-grammar.^find_method('parameter'); >
    }

my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
my $actions = $main-actions.^mixin(Nogil::NogilActions);
$*LANG.define_slang('MAIN', $grammar, $actions);

Не уверен, что это понятно: это похоже на вызов родительского токена в токене роли. Я знаю, что роль перезапишет ее, поэтому я сохранил резервную копию нетронутого объекта в $grammar.

Уже протестировано:

  1. Определите его как метод, возвращающий объект Match родительского объекта но получил следующую ошибку:
P6opaque: no such attribute '$!pos' on type NQPMatch in a Scalar when trying to get a value 
Возврат из интерполяции кода Regex
Attempt to return outside of immediately-enclosing Routine (i.e. `return` execution is outside the dynamic scope of the Routine where `return` was used)

1 Ответ

5 голосов
/ 02 апреля 2020

Intro: После многих подобных ошибок с nqp я понял:

Краткое описание: nqp + Scalar в сообщении об ошибке -> replace = на :=

Объясните: Используйте оператор связывания : = , а не присваивание = , которое при автоматической блокировке в скаляре приводит к ошибке сообщение со скаляром.

Демонстрация: Полностью рабочий пример (используйте в BEGIN phaser ). Попытка "my" сигил и "их" (скомпилировать на языке) на случай, если моя не удастся.

my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');

role Nogil::NogilGrammar {

    method sigil {
        # Bind
        my $sigil-they := $main-grammar.^find_method('sigil');
        my $sigil-me := self.sigil-eu;
        # Check My
        return $sigil-me if $sigil-me;
        # Return Their
        return $sigil-they(self);
    }

    token sigil-eu { '€' }
}

my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
$*LANG.define_slang('MAIN', $grammar, $main-actions);

Примечание 1: Я удалил некоторые say необходимые для демонстрации , Просто добавьте .Str к этим экзотериальным c объектам (NQPMatches).

Примечание2: Если вы хотите создать временные переменные (например, $res), сохраняйте привязку (:= ).

...