无法在语法操作类中绑定Nil类型对象中的属性

时间:2018-03-07 07:00:03

标签: grammar perl6

我正在调试更大的语法,并且能够将错误减少到以下最小的例子:

#! /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";我仍会得到相同的错误..

1 个答案:

答案 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);
}