Perl6:用俚语添加印记 [英] Perl6: Adding a sigil with Slangs

查看:48
本文介绍了Perl6:用俚语添加印记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加 «€» 作为 «$» 标量的别名,我认为用俚语来做这件事.但是 perl6.doc 根本没有提到俚语.

I am trying to add «€» as an alias for the «$» scalar, and doing it with a Slang is the way to do it I think. But perl6.doc doesn't mention Slangs at all.

我已阅读以下内容:

  • https://perlgeek.de/en/article/mutable-grammar-for-perl-6 (from 2008)
  • https://mouq.github.io/slangs.html

并查看了 Slang::Roman 和 Slang::Tuxic 模块.

And looked at the Slang::Roman and Slang::Tuxic modules.

结果是这个文件(ScalarEU.pm6):

The result is this file (ScalarEU.pm6):

use nqp;

unit module ScalarEU2;

sub EXPORT(|)
{
  my role Euscalar
  {
    token sigil:sym<$> { '€' | '$' }
  }

  my Mu $MAIN-grammar := nqp::atkey(%*LANG, 'MAIN');
  my $grammar := $MAIN-grammar.HOW.mixin($MAIN-grammar, Euscalar);

  $*LANG.define_slang('MAIN', $grammar, $*LANG.actions);

  {}
}

然后一个程序(称为 hello)使用它:

Then a program (called hello) using it:

use lib "lib";

use ScalarEU;

sub MAIN ($name)
{
  say "Hello, €name!";
}

但它不起作用,或者更确切地说,它没有做它应该做的:

But it doesn't work, or rather, doesn't do what it should:

$ ./hello Tom
Hello, €name!

(我是这样写程序的,这样它就不会崩溃.)

(I wrote the program this way so that it doesn't crash.)

我还没有添加动作类,但是令牌印记"的设置方式不应该要求这样做吗?但这个假设是基于一篇 11 年的文章,可能是错误的.

I haven't added an action class, but the way the "token sigil" is set up shouldn't require that? But that assumption is based on an 11 year article, and may be wrong.

另外,https://github.com/rakudo/rakudo/issues/2404 表示 $*LANG 已过时,而使用 $?LANG 代替.REPL 同意:

Also, https://github.com/rakudo/rakudo/issues/2404 says that $*LANG is obsolete, and to use $?LANG instead. REPL agrees:

> $*LANG
Dynamic variable $*LANG not found

> $?LANG
(low-level object `Perl6::Grammar`)

但是程序可以同时使用两者,不会出错.(我试过了.)

But programs can use both, without errors. (I have tried.)

推荐答案

简要说明:您必须更改 ParseShared$!target 字符串nqp 对象,这会在解析时更改代码.

Briefly: You must change $!target string of the ParseShared nqp object, this changes the code at parse time.

为什么:sigil 令牌不再是原型,而是定义了 rakudo/src/Perl6/Grammar.nqp 作为替代.

Why: The sigil token is not a proto anymore but defined rakudo/src/Perl6/Grammar.nqp as an alternation.

所以作为最小的解决方案:token sigil { <[$@%&€]>} 但随之而来的新问题是:返回值可以是 并用于其他语法.

So as a minimal solution: token sigil { <[$@%&€]> } but then comes new problem: the returned value can be and is used in other grammar.

地点:因此,您必须更改 nqp/src/QRegex/Cursor.nqp 为:

Where: So you must change $<sigil>.Str defined in nqp/src/QRegex/Cursor.nqp as:

method Str()       {
   $!pos >= $!from
        ?? nqp::substr(nqp::getattr_s($!shared, ParseShared, '$!target'),
            $!from, nqp::sub_i(self.to, $!from))
        !! '' }

<- 含义 如果 pos 不是那么低,则 target 中 from 和 to 之间的字符串.

-> 所以我们必须在 NQPMatch$!to 之间改变 $!target>.

-> So we must change $!target between $!from and $!to in a NQPMatch.

演示:这是嵌入俚语语法的代码:

Demo: Here is the code to embed in a slang grammar:

token sigil {
    | <[$@%&]>
    | <nogil> { say "Nogil returned: ", lk($/, 'nogil').Str; }
}

method nogil {
    # The object to return
    my $cursor := self.nogil-proxy;

    # Get from cursor
    my $shared := nqp::getattr($cursor, NQPMatch, '$!shared');
    my $from = nqp::getattr_i($cursor, NQPMatch, '$!from');
    my $target = $cursor.target;

    # Replace in target current character (€) by $
    $target.substr-rw($from, 1) = '$';

    # Set in cursor
    nqp::bindattr_s($shared, $shared.WHAT, '$!target', $target);

    # Return the "created by proxy" and modified NQPMatch
    return $cursor;
}

token nogil-proxy { '€' }

单独说:_它应该在您的情况下完美运行.在我的中,(没有符号)我仍然有问题,因为在 $!target 修改期间大小的变化会混淆其他游标的 tofrom.在这种情况下:

Speaking alone:_ It should work perfect in your case. In mine, (no sigil) I still have problem because the size changes during the $!target modification messes the to and from of other cursors. In which case:

  1. 我必须覆盖 NQPMatch.Str 函数(希望有可能).
  2. 我必须列出游标(如果可能)并明智地更改它们的 $!from$!to 属性,以恢复银河系或至少在客户端代码中的和平.
  1. I must overwrite NQPMatch.Str function (hoping it is possible).
  2. I must list cursors (if possible) and change their $!from and $!to attribute wisely to restore peace in the galaxy or at least in the client code.

这篇关于Perl6:用俚语添加印记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆