 
 
 
 
 
 
 
 
 
 










 
$ cat include.l
%x incl
%{
#define yywrap() 1
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr = 0;
%}
%%
include          BEGIN(incl);
.                ECHO;
<incl>[ \t]*
<incl>[^ \t\n]+  { /* got the file name */
                   if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
                     fprintf(stderr,"Includes nested too deeply\n");
                     exit(1);
                   }
                   include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
                   yyin = fopen(yytext,"r");
                   if (!yyin) {
                     fprintf(stderr,"File %s not found\n",yytext);
                     exit(1);
                   }
                   yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
                   BEGIN(INITIAL);
                 }
<<EOF>> {
          if ( --include_stack_ptr < 0) {
            yyterminate();
          } else {
            yy_delete_buffer(YY_CURRENT_BUFFER);
            yy_switch_to_buffer(include_stack[include_stack_ptr]);
          }
        }
%%
main(int argc, char ** argv) {
 
  yyin = fopen(argv[1],"r");
  yylex();
}
La función yy_create_buffer(yyin, YY_BUF_SIZE)); crea  un buffer
lo suficientemente grande para mantener YY_BUF_SIZE caracteres. Devuelve un 
YY_BUFFER_STATE, que puede ser pasado a otras rutinas. YY_BUFFER_STATE es un puntero a
una estructura de datos opaca (struct yy_buffer_state) que contiene la información para la manipulación
del buffer. Es posible por tanto inicializar un puntero YY_BUFFER_STATE
usando la expresión ((YY_BUFFER_STATE) 0).
La función yy_switch_to_buffer(YY_BUFFER_STATE new_buffer); conmuta la entrada 
del analizador léxico. La función void yy_delete_buffer( YY_BUFFER_STATE buffer )
se usa para recuperar la memoria consumida por un buffer.  También se pueden limpiar 
los contenidos actuales de un buffer llamando a:
void yy_flush_buffer( YY_BUFFER_STATE buffer )
La regla especial <<EOF>> indica la acción a ejecutar cuando 
se ha encontrado un final de fichero e yywrap() retorna un valor
distinto de cero. Cualquiera que sea la acción asociada, esta debe terminar 
con uno de estos cuatro supuestos:
yyin a un nuevo fichero de entrada.
return.
yyterminate().
yy_switch_to_buffer().
La regla <<EOF>> no se puede mezclar con otros patrones.
Este es el resultado de una ejecución del programa:
$ cat hello.c
#include hello2.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:>);
%>
$ cat hello2.c
#include hello3.c
/* file hello2.c  */
$ cat hello3.c
/*
third file
*/
$ flex include.l ; gcc lex.yy.c ; a.out hello.c
##/*
third file
*/
 
/* file hello2.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:>);
%>                                                            
Una alternativa a usar el patrón <<EOF>>
es dejar la responsabilidad de recuperar el buffer anterior
a yywrap(). En tal caso suprimiríamos esta parajea patrón-acción
y reescribiríamos yywrap():
%x incl
%{
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr = 0;
%}
%%
include          BEGIN(incl);
.                ECHO;
<incl>[ \t]*
<incl>[^ \t\n]+  { /* got the file name */
                   if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
		     fprintf(stderr,"Includes nested too deeply\n");
		     exit(1);
		   }
		   include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
		   yyin = fopen(yytext,"r");
		   if (!yyin) {
		     fprintf(stderr,"File %s not found\n",yytext);
		     exit(1);
		   }
		   yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
		   BEGIN(INITIAL);
		 }
%%
main(int argc, char ** argv) {
  yyin = fopen(argv[1],"r");
  yylex();
}
int yywrap() {
  if ( --include_stack_ptr < 0) { 
    return 1;
  } else {
    yy_delete_buffer(YY_CURRENT_BUFFER);
    yy_switch_to_buffer(include_stack[include_stack_ptr]);
    return 0;
  }
}
 
 
 
 
 
 
 
 
 
 










