next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: La pila de estados Sup: Expresiones Regulares en Flex Ant: yyless() Err: Si hallas una errata ...

Estados

Las expresiones regulares pueden ser prefijadas mediante estados. Los estados o condiciones de arranque, se denotan mediante un identificador entre ángulos y se declaran en la parte de las definiciones. Las declaraciones se hacen mediante %s para los estados ``inclusivos'' o bien %x para los estados ``exclusivos'', seguidos de los nombres de los estados. No pueden haber caracteres en blanco antes de la declaración. Un estado se activa mediante la acción BEGIN estado. A partir de ese momento, las reglas que esten prefijadas con el estado pasan a estar activas. En el caso de que el estado sea inclusivo, las reglas no prefijadas también permanecen activas. Los estados exclusivos son especialmente útiles para especificar ``sub analizadores'' que analizan porciones de la entrada cuya estructura ``sintáctica'' es diferente de la del resto de la entrada.

El ejemplo ``absorbe'' los comentarios, conservando el numero de líneas del fichero en la variable linenum

$ cat comments.l
%option noyywrap
%{
  int linenum = 0;
%}
%x comment
%%
 
"/*" BEGIN(comment); printf("comment=%d, YY_START = %d, YYSTATE = %d",comment,YY_START,YYSTATE);
<comment>[^*\n]* /* eat anything that is not a star * /
<comment>"*"+[^*/\n]* /* eat up starts not followed by / */
<comment>\n ++linenum; /* update number of lines */
<comment>"*"+"/" BEGIN(0);
 
\n ECHO; linenum++;
.  ECHO;
%%
main() {
  yylex();
  printf("\n%d lines\n",linenum);
}
La opción noyywrap hace que yylex() no llame a la función yywrap() al final del fichero y que asuma que no hay mas entrada por procesar.

Los estados se traducen por enteros, pudiendo ser manipulados como tales. La macro INITIAL puede utilizarse para referirse al estado 0. Las macros YY_START y YYSTATE contienen el valor del estado actual.

$ flex comments.l ; gcc lex.yy.c ; a.out < hello.c
main() <%
int a<:1:>; comment=1, YY_START = 1, YYSTATE = 1
  a<:0:> = 4; comment=1, YY_START = 1, YYSTATE = 1
  printf("hello world! a(0) is %d\n",a<:0:>);
%>
 
6 lines     
$ cat hello.c
main() <%
int a<:1:>; /* a comment */
  a<:0:> = 4; /* a comment in
                 two lines */
  printf("hello world! a(0) is %d\n",a<:0:>);
%>                                  
En flex es posible asociar un ámbito con los estados o condiciones iniciales. Basta con colocar entre llaves las parejas patrón acción gobernadas por ese estado. El siguiente ejemplo procesa las cadenas C:
$ cat ststring.l
%option main
%x str
%{
#define MAX_STR_CONST 256
 
  char string_buffer[MAX_STR_CONST];
  char *string_buf_ptr;
%}
 
%%
\"  string_buf_ptr  = string_buffer; BEGIN(str);
<str>{
\"             {BEGIN (INITIAL); *string_buf_ptr = '\0'; printf("%s",string_buffer); }
\n             { printf("Error: non terminated string\n"); exit(1); }
\\[0-7]{1,3}   { int result; /* octal escape sequence */
                        (void) sscanf(yytext+1,"%o",&result);
                         if (result > 0xff) {printf("Error: constant out of bounds\n"); exit(2); }
                         *string_buf_ptr++ = result;
                    }
\\[0-9]+       { printf("Error: bad escape sequence\n"); exit(2); }
\\n            {*string_buf_ptr++ = '\n';}
\\t            {*string_buf_ptr++ = '\t';}
\\b            {*string_buf_ptr++ = '\b';}
\\r            {*string_buf_ptr++ = '\r';}
\\f            {*string_buf_ptr++ = '\f';}
\\(.|\n)       {*string_buf_ptr++ = yytext[1];}
[^\\\n\"]+     {char *yptr = yytext; while(*yptr) *string_buf_ptr++ = *yptr++; }
}
(.|\n)
%%                            
$ flex ststring.l ; gcc lex.yy.c ; a.out < hello.c
        hello
world! a(0) is %d
$ cat hello.c
main() <%
int a<:1:>; /* a comment */
  a<:0:> = 4; /* a comment in
                 two lines */
  printf("\thell\157\nworld! a(0) is %d\n",a<:0:>);
%>                                   
Obsérve la conducta del programa ante las siguientes entradas:


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: La pila de estados Sup: Expresiones Regulares en Flex Ant: yyless() Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22