我正在调试更大的语法,并且能够将错误减少到以下最小的例子:
#! /usr/bin/env perl6
use v6;
my $str = q:to/END/;
bar baz, bak
END
class Actions {
method arg-separator ($match-data) {
my $match-str = $match-data.Str;
if $match-str ~~ /^ \s+ $/ {
make ", ";
}
else {
make $match-str;
}
}
}
grammar Simple-Grammar {
token TOP { ^ \s* [[<argument> <arg-separator>]* <argument>] \s* $ }
token argument {
[<!before <arg-separator>> . ]+
}
token arg-separator {
[<!before <eos>> \s+] || [\s* ',' [<!before <eos>> \s*]]
}
token eos { \s* $ }
}
Simple-Grammar.parse( $str, actions => Actions.new);
输出:
Cannot bind attributes in a Nil type object
in method arg-separator at ./p.p6 line 16
in regex arg-separator at ./p.p6 line 28
in regex argument at ./p.p6 line 24
in regex TOP at ./p.p6 line 22
in block <unit> at ./p.p6 line 35
第16行在这里
make $match-str;
我不明白为什么$match-str
在这里Nil type object
?奇怪的是,如果我用第16行中的$match-str
替换任何常量字符串,例如make "xxx";
我仍会得到相同的错误..
答案 0 :(得分:3)
正在运行make $match-str
尝试将$match-str
作为匹配数据附加到$/
,请参阅documentation。但是,$/
并不是您认为的那样。先前的陈述
$match-str ~~ /^ \s+ $/
由于匹配失败,将$/
隐式设置为Nil
。因此,您收到错误消息:
Cannot bind attributes in a Nil type object
尝试将$match-str
附加到$/
时。解决方案是在这种情况下不使用$/
,而不是
if $match-str ~~ /^ \s+ $/ {
make ", ";
}
else {
make $match-str;
}
您应该在make
上明确调用$match-data
方法:
if $match-str ~~ /^ \s+ $/ {
$match-data.make(", ");
}
else {
$match-data.make($match-str);
}