<autoscore>
aparece
en cualquier producción de una variable sintáctica,
el código especificado por la misma es utilizado
como código para la puntuación de la producción
dentro de las producciones de la variable sintáctica.
Con la excepción, claro está, de aquellas reglas
que tuvieran ya una directiva score
explícitamente
asignada. El código de la gramática queda como sigue:
my $grammar = q{ line : <autoscore: @{$item[1]}> | <leftop: value ',' value> | <leftop: datum ':' datum> | <leftop: field ";" field> value: /[^,]*/ datum: /[^:]*/ field: /[^;]*/ };
Por defecto, el analizador generado por parse::RecDescent
siempre acepta
la primera producción que reconoce un prefijo de la entrada. Como
hemos visto, se puede cambiar esta conducta
usando la directiva <score: ...>
. Las diferentes
producciones son intentadas y su puntuación (score
) evaluada, considerándose
vencedora aquella con mayor puntuación. Esto puede usarse para
hacer que la regla vencedora sea ``la mas larga'', en el sentido de ser
la que mas elementos
en @item
deja.
En este caso tomamos ventaja de la directiva <autoscore>
,
la cual permite
asociar una directiva <score>
con cada producción que no tenga ya una directiva
<score>
explícita.
#!/usr/local/bin/perl5.8.0 -w use strict; use warnings; use Parse::RecDescent; $::RD_TRACE = 1; #$::RD_HINT = 1; my $grammar = q { start: seq_1 ';' seq_1 : <autoscore: @item> | 'A' 'B' 'C' 'D' { local $^W = 0; print "seq_1: " . join (" ", @item[1..$#item]) . " score: $score\n" } | 'A' 'B' 'C' 'D' 'E' 'F' { print "seq_1: " . join (" ", @item[1..$#item]) . " score: $score\n" } }; my $parser; { local $^W = 0; # Avoid warning "uninitialized value in (m//) at RecDescent.pm line 626." $parser=Parse::RecDescent->new($grammar); } my $result = $parser->start("A B C D E F ;"); if (defined($result)) { print "Valida\n"; } else { print "No reconocida\n"; }