

[:,\t]) que se repite mas veces en la
línea. Por ejemplo, la línea:
a:1,b:2,c:3,dse separará por comas produciendo la lista
["a:1", "b:2","c:3","d"],
pero la línea
a:1,b:2,c:3:dse separará mediante el carácter dos puntos produciendo la lista
["a","1,b", "2,c","3","d"].
Para resolver el problema se declaran dos variables max
y $maxcount locales
al método asociado con la variable sintáctica line que reconoce la
categoría gramatical línea. Para declarar tales variables
se usa la directiva rulevar.
La otra directiva que se usa es reject, la cuál hace
que la producción falle (exactamente igual que si la acción
hubiese retornado undef). La estrategia consiste
en almacenar en, separador por separador llevar en $maxcount
el máximo número de items en que se descompone la línea
y en $max la referencia al array anónimo ``ganador''.
#!/usr/local/bin/perl5.8.0 -w
use strict;
use Parse::RecDescent;
use Data::Dumper;
#$::RD_TRACE = 1;
my $grammar = q{
line : <rulevar: $max>
line : <rulevar: $maxcount = 0>
line : <leftop: value ',' value>
{ $maxcount = @{$item[1]}; $max = $item[1];
print "maxcount[,] = $maxcount\n"; }
<reject>
| <leftop: datum ':' datum>
{ if (@{$item[1]} > $maxcount) {
$maxcount = @{$item[1]}; $max = $item[1]; }
print "maxcount[,:] = $maxcount\n";
}
<reject>
| <leftop: field ";" field>
{ if (@{$item[1]} > $maxcount) {
$maxcount = @{$item[1]}; $max = $item[1]; }
print "maxcount[,:;] = $maxcount\n";
}
<reject>
| { $return = $max; }
value: /[^,]*/
datum: /[^:]*/
field: /[^;]*/
};
my $parse = Parse::RecDescent->new($grammar);
my $line;
while ($line = <>) {
print "$line\n";
my $result = $parse->line($line);
if (defined($result)) { print Dumper($result); }
else { print "Cadena no válida\n"; }
}
Probemos el código con el siguiente fichero de entrada:
cat file3.txt 1:2:3,3:4;44 1,2:3,3:4;44 1;2:3;3:4;44He aqui una ejecución:
$ ./maxseparator.pl file3.txt 1:2:3,3:4;44 maxcount[,] = 2 maxcount[,:] = 4 maxcount[,:;] = 4 $VAR1 = [ '1', '2', '3,3', '4;44 ' ]; 1,2:3,3:4;44 maxcount[,] = 3 maxcount[,:] = 3 maxcount[,:;] = 3 $VAR1 = [ '1', '2:3', '3:4;44 ' ]; 1;2:3;3:4;44 maxcount[,] = 1 maxcount[,:] = 3 maxcount[,:;] = 4 $VAR1 = [ '1', '2:3', '3:4', '44 ' ];

