我正在尝试将«€»作为«$»标量的别名添加,我认为使用lang语来完成它是一种方法。但是perl6.doc完全没有提到S语。
我已阅读以下内容:
并查看了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
时更改大小会弄乱其他游标的to
和from
。在这种情况下:$!from
和$!to
属性,以恢复银河系或至少在客户端代码中的和平。