Какие аргументы передаются в действие Marpa::R2?

На странице cpan в Marpa :: R2 я понимаю BNF (форму Бэкуса-Наура), но я совершенно потерян с обратными вызовами действий.

В этом примере ниже я понимаю, что два, левый и правый члены передаются 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]? Где это задокументировано? Даже на официальном сайте Marpa я не вижу никакой документации.

В другом примере, здесь ответ choroba, мы видим, что pair относится к $_[2] а также $_[3]:

Фрагмент БНФ:

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] }

1 ответ

Решение

Документы Marpe::R2 говорят следующее:

sub My_Actions::do_add {
    my ( undef, $t1, undef, $t2 ) = @_;
    return $t1 + $t2;
}

Семантические замыкания в Perl являются обратными вызовами. Они вызываются при оценке каждого узла в дереве разбора.

Каждое семантическое замыкание Perl вызывается с одним или несколькими аргументами. Первым аргументом действия значения всегда является объект per-parse-tree, который обратные вызовы могут использовать в качестве блокнота. В этом примере объект per-parse-tree не используется. Остальные аргументы будут значениями "потомков" узла - другими словами, значениями, вычисленными для каждого из его символов RHS, по порядку. Если действие предназначено для пустого правила, его единственным аргументом будет объект per-parse-tree.

Ожидается, что каждое действие со значением возвращает значение. За одним исключением, это значение передается родительскому узлу в качестве аргумента. Исключением является значение для правила запуска. Возвращаемое значение для правила запуска становится результатом анализа.

Таким образом, этим функциям передается объект в качестве первого аргумента. Это $_[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
]
Другие вопросы по тегам