[Cascavel-pm] Gramáticas, Parse::RecDescent (era: Casos de Sucesso)

Adriano Ferreira a.r.ferreira em gmail.com
Terça Agosto 7 12:21:35 PDT 2007


On 8/7/07, Nelson Ferraz <nferraz em gmail.com> wrote:
> > On 8/7/07, Nelson Ferraz <nferraz em gmail.com> wrote:
> >> Vou fazer mais alguns testes com regexps, mas acho que vou partir
> >> logo para
> >> o Parse::RecDescent. Alguém aqui tem experiência com esse módulo?
> >
> > Eu usei ele há algum tempo atrás e achei bom. Tem excelentes
> > mensagens de debug.
>
> Realmente -- pelo pouco que usei já tive essa impressão.
>
> No entanto ainda não consegui perceber como retornar valores da
> gramática. Isto é; eu consigo verificar se o texto é válido, mas não
> consigo extrair as informações dele. Por exemplo:

O segredo são as "actions". O "autotree" mencionado pelo Eden define
automaticamente estas actions. Mas você pode defini-las regra a regra.

> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Parse::RecDescent;
>
> my $grammar = q{
>                  ini_file: section(s)
>                      section: section_label parameter(s) | <error>
>                          section_label: /\s*\[\w+\]\s*/
>                          parameter: key '=' value
>                              key: /\w+/
>                              value: /.*\n/
> };
>
> my $parser = Parse::RecDescent->new($grammar) or die "Invalid grammar!
> \n";
>
> my $text = do { local $/; <DATA> };
>
> if ( defined( my $result = $parser->ini_file($text) ) ) {
>      print "It's a valid input!\n";
>      use Data::Dumper;
>      print Dumper $result;
> }
> else {
>      print "No good.\n";
> }
>
> __DATA__
>
> [foo]
>
> a=1
> b=2
> c=3
>
> [bar]
>
> x=a
> y=b
> z=c
>
> __END__
>
> Como extrair essas informações (sections, parameters, values) de
> forma que elas possam ser trabalhadas?

Por exemplo,

sub build_hash {
    my %hash;
    for ( @{+shift} ) {
        $hash{ $_->[0] } = $_->[1];
    }
    return \%hash;
}

my $grammar = q{

ini_file: section(s)
          { $return = [ @item[1..$#item] ] }

section: section_label parameter(s)
         {  $return = { section => $item{section_label}, parameter =>
::build_hash($item[2]) }  }
       | <error>

section_label: /\s*\[/ /\w+/ /\]\s*/
               { $return = $item[2] }

parameter: key '=' value
           { $return = [ $item{key} => $item{value} ] }

key: /\w+/

value: /.*$/m
};

leva a seguinte estrutura quando o seu exemplo de entrada é usado:

It's a valid input!
$VAR1 = [
          [
            {
              'parameter' => {
                               'c' => '3',
                               'a' => '1',
                               'b' => '2'
                             },
              'section' => 'foo'
            },
            {
              'parameter' => {
                               'y' => 'b',
                               'x' => 'a',
                               'z' => 'c'
                             },
              'section' => 'bar'
            }
          ]
        ];


> _______________________________________________
> Cascavel-pm mailing list
> Cascavel-pm em pm.org
> http://mail.pm.org/mailman/listinfo/cascavel-pm
>


Mais detalhes sobre a lista de discussão Cascavel-pm