[Cascavel-pm] Parse de Endereço (Was: Re: Separando campos)

Luis Motta Campos luismottacampos em yahoo.co.uk
Quarta Março 21 01:00:52 PDT 2007


On Mar 20, 2007, at 5:39 PM, Daniel Ruoso wrote:
> Ter, 2007-03-20 às 17:35 +0100, Luis Motta Campos escreveu:
>>    Eu já disse: eu transformaria este monte de IFs em um Dispatch  
>> Table.
>>    http://en.wikipedia.org/wiki/Dispatch_table
>>    Eu não vou perder o meu tempo exercitando RTFM para você,
>> Daniel ;-) você já sabe fazer isso sozinho...
>
> ô filho, assim vc me ofende... Não estou perguntando o que é uma
> dispatch table, mas sim como você resolveria o problema em questão.  
> Vale
> lembrar que existem N maneiras de implementar um dispatch table em  
> Perl
> e existem M maneiras de utilizar uma dispatch table para resolver esse
> problema, logo dentre N * M, como você faria?

   Ô mãe, não quis ofender, apenas não quis implementar... ;-)
   Para me redimir do assunto:

   1. Eu estava errado sobre a dispatch table, veja a explicação no  
fonte;
   2. Eu implementei hoje, que não estou com pregui... ;-)

__PERL__
#!/bin/bash -- # -*- perl -*- -p
eval 'exec perl -wS $0 ${1+"$@"}'
   if $running_under_some_shell;

# Ah, é... o truque sujo acima é para garantir que o script roda no  
FreeBSD...
# Está listado no "perlrun", use "perldoc perlrun" para entender como  
funciona.

use strict;
use warnings;

## Observacoes:
#    1. Isto é uma técnica muito simples, chamada decomposição por
#       produções, utilizada para a construção de parsers guiados pelo
#       contexto. Para quem quiser saber mais sobre o assunto, eu  
recomendo ler
#       Aho, Sethi e Ullman, "Compilers: Principles, Techiniques and  
Tools",
#       ISBN-10: 0201100886, ISBN-13: 978-0201100884.

#    2. A minha primeira aproximação, de tentar refatorar o código  
original
#       usando uma dispatch table se mostrou menos elegante que isto.  
Por isso,
#       eu preferi mostrar este aqui. Eu volto a insistir: isto não  
tem nenhum
#       sentido prático, ninguém deveria pensar em uma biblioteca  
para fazer
#       extração de dados - extrair dados é um processo de  
alfaiataria: você
#       precisa ver o cliente e tirar as medidas, ou a roupa não vai  
cair bem.
#       Claro, isso não impede ninguém de implementar "tesouras" e  
"maquinas
#       de costurar" - claramente, este não é o caso...

# Produções
## 1. Logradouro
my $logradouro = qr{^(
                       [Rr](?:ua|\.)      |
                       [Aa](?:v\.|venida) |
                       [Tt](?:r\.|avessa) |
                       [Pp](?:r\.|aca)    |
                       [Ll](?:g\.|argo)
                      )
                  }x;

## 2. Nome do Logradouro
my $nome_do_logradouro = qr{(
                               [^,]+,  # Caso 1: nao-virgulas  
seguidas de virgula
                                       # Aqui devia vir o caso 2...
                             )
                          }x;

## 3. Numero da casa
my $numero_da_casa = qr{(\d+)}x;

## 4. Complemento
my $complemento = qr{(.+)}x; # outras regras para complemento
                              # podem fazer sentido aqui.

## 5. Outras informacoes Acrescentar outras informacoes a este parser  
guiado
#     pelo contexto eh simplesmente uma questao de implementar uma  
expressao regular
#     capaz de capturar e retornar o valor desejado e a colocar aqui.

sub extrair_endereco {
     local $_ = shift;
     # Olha, mamae! Sem IFs!
     return wantarray ?
       [ m{$nome_do_logradouro $numero_da_casa $complemento}x ]
       : ( m{$nome_do_logradouro $numero_da_casa $complemento}x );
}
__END__

   É isso.
   Putamplexos!
--
Luis Motta Campos (a.k.a. Monsieur Champs) is a software engineer,
Perl fanatic evangelist, and amateur {cook, photographer}




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