什么参数传递给 Marpa::R2 操作?
What arguments are passed to an Marpa::R2 action?
在 cpan page of Marpa::R2 中,我了解 BNF(Backus-Naur 形式),但我对操作回调感到很迷惑。
在下面的这个例子中,我了解到左右两个成员被传递给了do_multiply
。对于那件事我没有任何疑问。问题是我找不到任何关于这些参数的文档?
my $dsl = <<'END_OF_DSL';
:default ::= action => [name,values]
lexeme default = latm => 1
Calculator ::= Expression action => ::first
...
Term '*' Factor action => do_multiply
...
END_OF_DSL
my $grammar = Marpa::R2::Scanless::G->new( { source => $dsl } );
sub do_multiply { $_[1] * $_[2] }
什么是$_[0]
甚至$_[3]
?这在哪里记录?即使在 official marpa website 上,我也看不到任何文档。
在另一个例子中,here an answer of chobora,我们看到 pair
指的是 $_[2]
和 $_[3]
:
BNF 片段:
Hash ::= '(' Pairs ')' action => hash
Pairs ::= Pair+ action => pairs
Pair ::= '(' Key Value ')' action => pair
Key ::= String
核心代码:
$recce->read($input);
print Dumper $recce->value;
sub hash { $_[2] }
sub pairs { shift; +{ map @$_, @_ } }
sub pair { [ @_[2, 3] ] } # What is 2 and 3?
sub itself { $_[1] }
Marpe::R2 docs 说如下:
sub My_Actions::do_add {
my ( undef, $t1, undef, $t2 ) = @_;
return $t1 + $t2;
}
The Perl semantic closures are callbacks. They are called as each node
in a parse tree is evaluated.
Each Perl semantic closure is called with one or more arguments. The
first argument to a value action is always a per-parse-tree object,
which the callbacks can use as a scratchpad. In this example, the
per-parse-tree object is not used. The remaining arguments will be the
values of the node's "children" -- in other words, the values computed
for each of its RHS symbols, in order. If the action is for an empty
rule, the per-parse-tree object will be its only argument.
Every value action is expected to return a value. With one exception,
this value is passed up to a parent node as an argument. The exception
is the value for the start rule. The return value for the start rule
becomes the parse result.
所以这些函数被传递一个对象作为第一个参数。那是 $_[0]
.
对于您的示例,文本似乎意味着以下参数 $_[1]
和 $_[2]
只是您用来计算内容的值。
添加一些调试输出给了我以下内容:
use Data::Printer;
sub My_Actions::do_add {
my ( undef, $t1, undef, $t2 ) = @_;
say 'do_add';
p @_;
return $t1 + $t2;
}
sub My_Actions::do_multiply {
my ( undef, $t1, undef, $t2 ) = @_;
say 'do_multiply';
p @_;
return $t1 * $t2;
}
__END__
do_multiply
[
[0] {},
[1] 42,
[2] "*",
[3] 1
]
do_add
[
[0] {},
[1] 42,
[2] "+",
[3] 7
]
在 cpan page of Marpa::R2 中,我了解 BNF(Backus-Naur 形式),但我对操作回调感到很迷惑。
在下面的这个例子中,我了解到左右两个成员被传递给了do_multiply
。对于那件事我没有任何疑问。问题是我找不到任何关于这些参数的文档?
my $dsl = <<'END_OF_DSL';
:default ::= action => [name,values]
lexeme default = latm => 1
Calculator ::= Expression action => ::first
...
Term '*' Factor action => do_multiply
...
END_OF_DSL
my $grammar = Marpa::R2::Scanless::G->new( { source => $dsl } );
sub do_multiply { $_[1] * $_[2] }
什么是$_[0]
甚至$_[3]
?这在哪里记录?即使在 official marpa website 上,我也看不到任何文档。
在另一个例子中,here an answer of chobora,我们看到 pair
指的是 $_[2]
和 $_[3]
:
BNF 片段:
Hash ::= '(' Pairs ')' action => hash
Pairs ::= Pair+ action => pairs
Pair ::= '(' Key Value ')' action => pair
Key ::= String
核心代码:
$recce->read($input);
print Dumper $recce->value;
sub hash { $_[2] }
sub pairs { shift; +{ map @$_, @_ } }
sub pair { [ @_[2, 3] ] } # What is 2 and 3?
sub itself { $_[1] }
Marpe::R2 docs 说如下:
sub My_Actions::do_add { my ( undef, $t1, undef, $t2 ) = @_; return $t1 + $t2; }
The Perl semantic closures are callbacks. They are called as each node in a parse tree is evaluated.
Each Perl semantic closure is called with one or more arguments. The first argument to a value action is always a per-parse-tree object, which the callbacks can use as a scratchpad. In this example, the per-parse-tree object is not used. The remaining arguments will be the values of the node's "children" -- in other words, the values computed for each of its RHS symbols, in order. If the action is for an empty rule, the per-parse-tree object will be its only argument.
Every value action is expected to return a value. With one exception, this value is passed up to a parent node as an argument. The exception is the value for the start rule. The return value for the start rule becomes the parse result.
所以这些函数被传递一个对象作为第一个参数。那是 $_[0]
.
对于您的示例,文本似乎意味着以下参数 $_[1]
和 $_[2]
只是您用来计算内容的值。
添加一些调试输出给了我以下内容:
use Data::Printer;
sub My_Actions::do_add {
my ( undef, $t1, undef, $t2 ) = @_;
say 'do_add';
p @_;
return $t1 + $t2;
}
sub My_Actions::do_multiply {
my ( undef, $t1, undef, $t2 ) = @_;
say 'do_multiply';
p @_;
return $t1 * $t2;
}
__END__
do_multiply
[
[0] {},
[1] 42,
[2] "*",
[3] 1
]
do_add
[
[0] {},
[1] 42,
[2] "+",
[3] 7
]