next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Estados Sup: Expresiones Regulares en Flex Ant: yymore() Err: Si hallas una errata ...

yyless()

La función yyless(n) permite retrasar el puntero de lectura de manera que apunta al carácter n de yytext. Veamos un ejemplo:
$ cat yyless.l
%%
foobar ECHO; yyless(4);
[a-z]+ ECHO;
 
$ flex yyless.l; gcc lex.yy.c -lfl; a.out
foobar
foobarar
Veamos un ejemplo mas ``real''. supongamos que tenemos que reconocer las cadenas entre comillas dobles, pero que pueden aparecer en las mismas secuencias de escape \". La estrategia general del algoritmo es utilizar la expresión regular \"[^"]+\" y examinar si los dos últimos carácteres en yytext son \". En tal caso, se concatena la cadena actual (sin la " final) como prefijo para el próximo emparejamiento (utilizando yymore). La eliminación de la " se hace a través de la ejecución de yyless(yyleng-1), que al mismo tiempo garantiza que el próximo emparejamiento tendrá lugar con este mismo patrón \"[^"]+\".
$ cat quotes.l
%%
\"[^"]+\" {
            printf("Processing string. %d: %s\n",yyleng,yytext);
            if (yytext[yyleng-2] =='\\') {
             yyless(yyleng-1); /* so that it will match next time */
             yymore(); /* concatenate  with current yytext */
             printf("After yyless. %d: %s\n",yyleng,yytext);
            } else {
              printf("Finished. The string is: %s\n",yytext);
            }
          }
El ejemplo no puede entenderse si no se tiene en cuenta que yyless(yyleng-1) actualiza los valores de yyleng y yytext, como muestra la salida.
¿Qué ocurre si intercambiamos las posiciones de yymore() e yyless(yyleng-1) en el código? >Cambiara la salida? La respuesta es que no. Parece que la concatenación se hace con el valor final de yytext y no con el valor que este tenía en el momento de la llamada a yymore.
Otra observación a tener en cuenta es que yyless() es una macro y que, por tanto, sólo puede ser utilizada dentro del fichero lex y no en otros ficheros fuentes.

En general, el uso de estas funciones nos puede resolver el problema de reconocer límites que de otra forma serían difíciles de expresar con una expresión regular.

$ flex quotes.l ; gcc lex.yy.c -lfl ; a.out
"Hello \"Peter\", nice to meet you"
Procesing string. 9: "Hello \"
After yyless. 8: "Hello \
Procesing string. 16: "Hello \"Peter\"
After yyless. 15: "Hello \"Peter\
Procesing string. 35: "Hello \"Peter\", nice to meet you"
Finished. The string is: "Hello \"Peter\", nice to meet you"


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Estados Sup: Expresiones Regulares en Flex Ant: yymore() Err: Si hallas una errata ...
Casiano Rodríguez León
2013-03-05