next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Repaso: Fases de un Sup: La Estructura de los Ant: Práctica: Crear y documentar Err: Si hallas una errata ...


Las Fases de un Compilador

La estructura del compilador, descompuesto en fases, queda explicitada en el código de la subrutina compile:

 1 package PL::Tutu;
 2 use 5.008004;
 3 use strict;
 4 use warnings;
 5 use IO::File;
 6 use Carp;
 7 
 8 require Exporter;
 9 
10 our @ISA = qw(Exporter);
11 our @EXPORT = qw( compile compile_from_file);
12 our $VERSION = '0.01';
13 
14 our %symbol_table;
15 our $data;
16 our $target;
17 our @tokens;
18 our $errorflag;
19 our ($lookahead, $value);
20 our $tree;
21 our $global_address;
22 
23 # Lexical analyzer 
24 package Lexical::Analysis;
25 sub scanner {
26 }
27 
28 package Syntax::Analysis;
29 sub parser {
30 }
31 
32 package Machine::Independent::Optimization;
33 sub Optimize {
34 }
35 
36 package Code::Generation;
37 sub code_generator {
38 }
39   
40 package Peephole::Optimization;
41 sub transform {
42 }
43 
44 package PL::Tutu;
45 sub compile {
46   my ($input) = @_;
47   local %symbol_table = ();
48   local $data = ""; # Contiene todas las cadenas en el programa fuente
49   local $target = ""; # target code
50   local @tokens =();
51   local $errorflag = 0;
52   local ($lookahead, $value) = ();
53   local $tree = undef; # abstract syntax tree
54   local $global_address = 0;
55   
56   ########lexical analysis
57   &Lexical::Analysis::scanner($input);
58 
59   ########syntax (and semantic) analysis
60   $tree = &Syntax::Analysis::parser;
61 
62   ########machine independent optimizations
63   &Machine::Independent::Optimization::Optimize;
64 
65   ########code generation
66   &Code::Generation::code_generator;
67 
68   ########peephole optimization
69   &Peephole::Optimization::transform($target);
70 
71   return \$target;
72 }
73 
74 sub compile_from_file {
75   my ($input_name, $output_name) = @_; # Nombres de ficheros
76   my $fhi;
77   my $targetref;
78   
79   if ($input_name and (-r $input_name)) {
80     $fhi = IO::File->new("< $input_name");
81   }
82   else { $fhi = 'STDIN'; }
83 
84   ########source input
85   local $/ = undef;
86   my $input = <$fhi>;
87 
88   $targetref = compile($input);
89 
90   ########code output
91   my $fh = $output_name? IO::File->new("> $output_name") : 'STDOUT';
92   $fh->print($$targetref);
93   $fh->close;
94   1; 
95 }
96 
97 1;
98 # Sigue la documentación ...

Vamos a añadir un script que use el módulo PL::Tutu para asi poder ejecutar nuestro compilador:

lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/$ mkdir scripts
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ cd scripts/
A continuación creamos dos versiones del compilador tutu.pl y tutu y un programa de prueba test01.tutu:

... # despues de crear los ficheros
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ ls
test01.tutu  tutu  tutu.pl
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ cat tutu.pl
#!/usr/bin/perl -w -I../lib/
use PL::Tutu;

PL::Tutu::compile_from_file(@ARGV);
El programa tutu ilustra otra forma de conseguir que el intérprete Perl busque por la librearía que está siendo desarrollada, mediante el uso de use lib:

lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ cat tutu
#!/usr/bin/perl -w
use lib ('../lib');
use PL::Tutu;

&PL::Tutu::compile_from_file(@ARGV);
Veamos los contenidos del programa fuente test01.tutu que usaremos para hacer una prueba:
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ cat test01.tutu
int a,b;
a = 4
Ahora tenemos que añadir estos ficheros en MANIFEST para que formen parte del proyecto. En vez de eso lo que hacemos es crear un fichero MANIFEST.SKIP:
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ cat MANIFEST.SKIP
\.o$
^\.cvsignore$
/\.cvsignore$
\.cvsignore$
CVS/[^/]+$
^Makefile$
/Makefile$
^blib/
\.swp$
\.bak$
\.pdf$
\.ps$
\.sal$
pm_to_blib
\.pdf$
\.tar.gz$
\.tgz$
^META.yml$
Para saber mas sobre MANIFEST léa la sección 6.16.4.

Es necesario indicarle a Perl que los ficheros añadidos son ejecutables:

lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ cat Makefile.PL
use 5.008004;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME              => 'PL::Tutu',
    VERSION_FROM      => 'lib/PL/Tutu.pm', # finds $VERSION
    PREREQ_PM         => {}, # e.g., Module::Name => 1.1
    EXE_FILES         => [ 'scripts/tutu.pl', 'scripts/tutu' ],
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/PL/Tutu.pm', # retrieve abstract from module
       AUTHOR         => 'Lenguajes y Herramientas de Programacion <lhp@>') : ()),
);
Perl utilizará esa información durante la fase de instalación para instalar los ejecutables en el path de búsqueda.

A continuación hay que rehacer el Makefile:

lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ perl Makefile.PL
Writing Makefile for PL::Tutu
Para crear una versión funcional hacemos make:
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ make
cp scripts/tutu blib/script/tutu
/usr/bin/perl "-MExtUtils::MY" -e "MY->fixin(shift)" blib/script/tutu
cp scripts/tutu.pl blib/script/tutu.pl
/usr/bin/perl "-MExtUtils::MY" -e "MY->fixin(shift)" blib/script/tutu.pl
Manifying blib/man3/PL::Tutu.3pm
Para crear el MANIFEST hacemos make manifest:
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ make manifest
/usr/bin/perl "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
Added to MANIFEST: scripts/tutu
Comprobemos que el test de prueba generado automáticamente por h2xs se pasa correctamente:
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/PL-Tutu....ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.08 cusr +  0.00 csys =  0.08 CPU)

Podemos ahora ejecutar los guiones:

lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ cd scripts/
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ ls -l
total 12
-rw-r--r--  1 lhp lhp 15 2005-09-29 12:56 test01.tutu
-rwxr-xr-x  1 lhp lhp 92 2005-09-29 13:29 tutu
-rwxr-xr-x  1 lhp lhp 80 2005-09-29 12:58 tutu.pl
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ tutu test01.tutu test01.sal
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu/scripts$ ls -l
total 12
-rw-r--r--  1 lhp lhp  0 2005-09-29 13:53 test01.sal
-rw-r--r--  1 lhp lhp 15 2005-09-29 12:56 test01.tutu
-rwxr-xr-x  1 lhp lhp 92 2005-09-29 13:29 tutu
-rwxr-xr-x  1 lhp lhp 80 2005-09-29 12:58 tutu.pl

Para hacer una distribución instalable hacemos make dist:

lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ make dist
rm -rf PL-Tutu-0.01
/usr/bin/perl "-MExtUtils::Manifest=manicopy,maniread" \
        -e "manicopy(maniread(),'PL-Tutu-0.01', 'best');"
mkdir PL-Tutu-0.01
mkdir PL-Tutu-0.01/scripts
mkdir PL-Tutu-0.01/lib
mkdir PL-Tutu-0.01/lib/PL
mkdir PL-Tutu-0.01/t
tar cvf PL-Tutu-0.01.tar PL-Tutu-0.01
PL-Tutu-0.01/
PL-Tutu-0.01/scripts/
PL-Tutu-0.01/scripts/test01.tutu
PL-Tutu-0.01/scripts/tutu
PL-Tutu-0.01/scripts/tutu.pl
PL-Tutu-0.01/META.yml
PL-Tutu-0.01/Changes
PL-Tutu-0.01/MANIFEST
PL-Tutu-0.01/lib/
PL-Tutu-0.01/lib/PL/
PL-Tutu-0.01/lib/PL/Tutu.pm
PL-Tutu-0.01/MANIFEST.SKIP
PL-Tutu-0.01/t/
PL-Tutu-0.01/t/PL-Tutu.t
PL-Tutu-0.01/Makefile.PL
PL-Tutu-0.01/README
rm -rf PL-Tutu-0.01
gzip --best PL-Tutu-0.01.tar
Después de esto tenemos en el directorio de trabajo el fichero PL-Tutu-0.01.tar.gz con la distribución:
lhp@nereida:~/Lperl/src/topdown/PL0506/02fases/PL-Tutu$ ls -ltr
total 72
drwxr-xr-x  2 lhp lhp  4096 2005-09-29 12:01 t
-rw-r--r--  1 lhp lhp  1196 2005-09-29 12:01 README
drwxr-xr-x  3 lhp lhp  4096 2005-09-29 12:01 lib
-rw-r--r--  1 lhp lhp   152 2005-09-29 12:01 Changes
-rw-r--r--  1 lhp lhp   167 2005-09-29 13:23 MANIFEST.SKIP
-rw-r--r--  1 lhp lhp     0 2005-09-29 13:23 pm_to_blib
drwxr-xr-x  6 lhp lhp  4096 2005-09-29 13:23 blib
-rw-r--r--  1 lhp lhp   113 2005-09-29 13:23 MANIFEST.bak
drwxr-xr-x  2 lhp lhp  4096 2005-09-29 13:29 scripts
-rw-r--r--  1 lhp lhp   616 2005-09-29 13:49 Makefile.PL
-rw-r--r--  1 lhp lhp 20509 2005-09-29 13:51 Makefile
-rw-r--r--  1 lhp lhp  3654 2005-09-29 16:34 PL-Tutu-0.01.tar.gz
-rw-r--r--  1 lhp lhp   298 2005-09-29 16:34 META.yml
-rw-r--r--  1 lhp lhp   205 2005-09-29 16:34 MANIFEST



Subsecciones
next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Repaso: Fases de un Sup: La Estructura de los Ant: Práctica: Crear y documentar Err: Si hallas una errata ...
Casiano Rodríguez León
2006-02-21