Как повторно использовать языковой токен в пользовательской грамматике (Raku)

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

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

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 
  1. Возврат из интерполяции кода 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 ответ

Решение

Введение: После множества похожих ошибок с nqp я понял:

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

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

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

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 этим экзотерическим объектам (NQPMatches).

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

Другие вопросы по тегам