










Sig: La Clase Parse::CLex
Sup: La clase Parse::Lex
Ant: La clase Parse::Lex
Err: Si hallas una errata ...
Los tokens pueden ser prefijados por ``condiciones de arranque'' o ``estados''.
Por ejemplo:
qw(C1:T1 er1), sub { # acción },
qw(T2 er2), sub { # acción },
el símbolo T1 será reconocido únicamente si el estado T1 está activo. Las
condiciones de arranque se activan utilizando
el método start(condicion) y se desactivan mediante end(condicion).
La llamada start('INITIAL') nos devuelve a la condición inicial.
> cat -n expectfloats.pl
1 #!/usr/bin/perl -w
2 use Parse::Lex;
3 @token = (
4 'EXPECT', 'expect-floats', sub {
5 $lexer->start('expect');
6 $_[1]
7 },
8 'expect:FLOAT', '\d+\.\d+',
9 'expect:NEWLINE', '\n', sub { $lexer->end('expect') ; $_[1] },
10 'expect:SIGN','[+-]',
11 'NEWLINE2', '\n',
12 'INT', '\d+',
13 'DOT', '\.',
14 'SIGN2','[+-]'
15 );
16
17 Parse::Lex->exclusive('expect');
18 $lexer = Parse::Lex->new(@token);
19
20 $lexer->from(\*DATA);
21
22 TOKEN:while (1) {
23 $token = $lexer->next;
24 if (not $lexer->eoi) {
25 print $token->name," ";
26 print "\n" if ($token->text eq "\n");
27 } else {
28 last TOKEN;
29 }
30 }
31
32 __END__
33 1.4+2-5
34 expect-floats 1.4+2.3-5.9
35 1.5
Ejecución:
> expectfloats.pl
INT DOT INT SIGN2 INT SIGN2 INT NEWLINE2
EXPECT FLOAT SIGN FLOAT SIGN FLOAT NEWLINE
INT DOT INT NEWLINE2
El siguiente ejemplo elimina los comentarios anidados en un programa C:
> cat -n nestedcom.pl
1 #!/usr/local/bin/perl -w
2
3 require 5.004;
4 #BEGIN { unshift @INC, "../lib"; }
5
6 $^W = 0;
7 use Parse::Lex;
8
9 @token = (
10 'STRING', '"([^\"]|\\.)*"', sub { print "$_[1]"; $_[1]; },
11 'CI', '\/\*', sub { $lexer->start('comment'); $c++; $_[1]; },
12 'CF', '\*\/', sub { die "Error, comentario no finalizado!"; },
13 'OTHER', '(.|\n)', sub { print "$_[1]"; $_[1]; },
14 'comment:CCI', '\/\*', sub { $c++; $_[1]; },
15 'comment:CCF', '\*\/', sub { $c--; $lexer->end('comment') if ($c == 0); $_[1]; },
16 'comment:COTHER', '(.|\n)'
17 );
18
19 #Parse::Lex->trace;
20 Parse::Lex->exclusive('comment');
21 Parse::Lex->skip('');
22
23 $lexer = Parse::Lex->new(@token);
24
25 $lexer->from(\*DATA);
26
27 $lexer = Parse::Lex->new(@token);
28
29 $lexer->from(\*DATA);
30
31 TOKEN:while (1) {
32 $token = $lexer->next;
33 last TOKEN if ($lexer->eoi);
34 }
35
36 __END__
37 main() { /* comment */
38 printf("hi! /* \"this\" is not a comment */"); /* another /*nested*/
39 comment */
40 }
Al ejecutarlo, produce la salida:
> nestedcom.pl
main() {
printf("hi! /* \"this\" is not a comment */");
}











Sig: La Clase Parse::CLex
Sup: La clase Parse::Lex
Ant: La clase Parse::Lex
Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22