我正在尝试将«€»作为«$»标量的别名添加,我认为使用lang语来完成它是一种方法。但是perl6.doc完全没有提到S语。

我已阅读以下内容:

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

  • 并查看了Slang::Roman和Slang::Tuxic模块。

    结果是此文件(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):
    use lib "lib";
    
    use ScalarEU;
    
    sub MAIN ($name)
    {
      say "Hello, €name!";
    }
    

    但这行不通,或者说行不通:
    $ ./hello Tom
    Hello, €name!
    

    (我以这种方式编写了程序,以免崩溃。)

    我还没有添加 Action 类,但是“ token 标记”的设置方式不应该要求吗?但是这个假设是基于11年的文章,可能是错误的。

    另外,https://github.com/rakudo/rakudo/issues/2404表示$ * LANG已过时,而改用$?LANG。 REPL同意:
    > $*LANG
    Dynamic variable $*LANG not found
    
    > $?LANG
    (low-level object `Perl6::Grammar`)
    

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

    最佳答案

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

    原因:sigil token 不再是原型(prototype),而是将rakudo/src/Perl6/Grammar.nqp定义为替代。

    因此,作为一个最小的解决方案:token sigil { <[$@%&€]> },但随后出现了新问题:返回的值可以是,并在其他语法中使用。

    其中:
    因此,您必须将nqp/src/QRegex/Cursor.nqp中定义的$<sigil>.Str更改为:

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

    The string in target between from and to if pos is not so low。

    ->因此,我们必须在$!target中的$!from$!to之间更改NQPMatch

    演示:
    这是嵌入in语语法中的代码:
    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。在这种情况下:
  • 我必须overwrite NQPMatch.Str function(希望是可行的)。
  • 我必须列出游标(如果可能的话),并明智地更改其$!from$!to属性,以恢复银河系或至少在客户端代码中的和平。
  • 10-07 14:59