

do i = 1, 10 es equivalente a la cadena
DOI=1,10. Un conocido conflicto ocurre entre una cadena
con la estructura do i = 1.10 (esto es DOI=1.10) y
la cadena anterior. En la primera DO e I son dos
``tokens'' diferentes, el primero correspondiendo a la palabra reservada que indica un bucle. En la segunda, DOI constituye un único ``token''
y la sentencia se refiere a una asignación.
El conflicto puede resolverse utilizando el operador de ``trailing'' r/s.
Como se mencionó, el operador de ``trailing''r/s permite reconocer una r pero sólo si va seguida de una s. El texto casado con s se incluye a la hora de decidir cual es el emparejamiento mas largo, pero se devuelve a la entrada cuando se ejecuta la acción. La acción sólo ve el texto asociado con r. El fichero fortran4.l ilustra una posible solución:
cat fortran4.l
%array
%{
#include <string.h>
#undef YY_INPUT
#define YY_INPUT(buf,result,max) (result = my_input(buf,max))
%}
number [0-9]+
integer [+-]?{number}
float ({integer}\.{number}?|\.{number})(E{integer})?
label [A-Z0-9]+
id [A-Z]{label}*
%%
DO/{label}={number}\, { printf("do loop\n"); }
{id} { printf("Identifier %s\n",yytext); }
{number} { printf("Num %d\n",atoi(yytext)); }
{float} { printf("Float %f\n",atof(yytext)); }
(.|\n)
%%
int my_input(char *buf, int max)
{
char *q1, *q2, *p = (char *) malloc(max);
int i;
if ('\0' != fgets(p,max,yyin)) {
for(i=0, q1=buf, q2=p;(*q2 != '\0');q2++) {
if (*q2 != ' ') { *q1++ = toupper(*q2); i++; };
}
free(p);
return i;
}
else exit(1);
}
La función
char *fgets(char *s, int size, FILE *stream)
lee a lo mas uno menos que size caracteres desde stream y los almacena en el buffer
apuntado por s. La lectura termina después de un EOF o un retorno de carro.
Si se lee un \n, se almacena en el buffer. La función pone un carácter nulo \0
como último carácter en el buffer.
A continuación, puedes ver los detalles de una ejecución:
$ flex fortran4.l; gcc lex.yy.c -lfl; a.out do j = 1 . 10 Identifier DOJ Float 1.100000 do k = 1, 5 do loop Identifier K Num 1 Num 5

