Estoy intentando analizar un campo de autor de BibTeX y dividirlo en sus autores separados. Esto me ayudará a reescribir las iniciales de cada autor. Aquí hay un ejemplo mínimo:

use v6;

my $str = '{Rockhold, Mark L and Yarwood, RR and Selker, John S}';

grammar BibTexAuthor {
    token TOP {
        <all-text> 
    }
    token all-text {
        '{' <authors> '}' 
    }
    token authors { 
        [<author> [' and ' || <?before '}'>]]+
    }
    token author {
        [<-[\s}]> || [' ' <!before 'and '>]]+
    }
}

class BibTexAuthor-actions {
    method TOP($/) {
        say $/;
        print "First author = ";
        say $<author>.made[0];
        make $/.Str;
    }
    method all-text($/) {
        make $/.Str;
    }
    method authors($/) {
        make $/.Str;
    }
    method author($/) {
        make $/.Str;
    }
}
my $res = BibTexAuthor.parse( $str, actions => BibTexAuthor-actions.new).made;

Salida :

「{Rockhold, Mark L and Yarwood, RR and Selker, John S}」
 all-text => 「{Rockhold, Mark L and Yarwood, RR and Selker, John S}」
  authors => 「Rockhold, Mark L and Yarwood, RR and Selker, John S」
   author => 「Rockhold, Mark L」
   author => 「Yarwood, RR」
   author => 「Selker, John S」
First author = Nil

¿Por qué no puedo extraer el primer autor en el método TOP?

3
Håkon Hægland 12 nov. 2017 a las 14:36

2 respuestas

La mejor respuesta

¿Por qué no puedo extraer el primer autor en el método TOP?

Porque realmente no está extrayendo ningún dato en los métodos de acción. Todo lo que debe hacer es adjuntar la cadena de la coincidencia a $/.made, que en realidad no es la información que desea al final.

Si desea tener autores separados al final, debe make una matriz de autores en el método de acción authors. Por ejemplo:

use v6;

my $str = '{Rockhold, Mark L and Yarwood, RR and Selker, John S}';

grammar BibTexAuthor {
    token TOP {
        <all-text> 
    }
    token all-text {
        '{' <authors> '}' 
    }
    token authors { 
        [<author> [' and ' || <?before '}'>]]+
    }
    token author {
        [<-[\s}]> || [' ' <!before 'and '>]]+
    }
}

class BibTexAuthor-actions {
    method TOP($/) {
        make { authors => $<all-text>.made };
    }
    method all-text($/) {
        make $/<authors>.made;
    }
    method authors($/) {
        make $/<author>».made;
    }
    method author($/) {
        make $/.Str;
    }
}
my $res = BibTexAuthor.parse( $str, actions => BibTexAuthor-actions.new).made;

say $res.perl;

Huellas dactilares

${:authors($["Rockhold, Mark L", "Yarwood, RR", "Selker, John S"])}

Así que ahora el .made de la coincidencia de nivel superior es un hash, donde la clave authors contiene una matriz. Si desea acceder al primer autor, ahora puede decir

say $res<authors>[0];

Para obtener Rockhold, Mark L

5
piojo 12 nov. 2017 a las 14:07
$<all-text><authors><author>[0];

Tenga en cuenta que no tengo idea de cómo funcionan las gramáticas hasta ahora. Estoy aprendiendo el idioma como tú.

Pero con solo mirar la estructura de datos es fácil darse cuenta de que es un árbol y en qué parte de ese árbol está el valor que está buscando.

Puede generar cualquier estructura de datos diciendo

dd $someStructure;
say $someStructure.perl;

Y si lo encuentra ilegible, puede probar uno de los módulos de volquete

4
Holli 12 nov. 2017 a las 13:15