yytext regulares programas lexico introduccion expresiones entre ejemplos ejemplo diferencia descargar compilar analizador flex-lexer

flex lexer - regulares - Dificultad para obtener comentarios de estilo c en flex/lex



introduccion a flex (8)

Aquí hay un ejemplo en caso de que alguien esté confundido acerca de cómo trabajar la respuesta de zneak:

(Básicamente, pones "% x C_COMMENT" en la primera sección y el resto en la segunda sección, como lo explica su enlace útil)

foo.l %{ // c code.. %} %x C_COMMENT %% "/*" { BEGIN(C_COMMENT); } <C_COMMENT>"*/" { BEGIN(INITIAL); } <C_COMMENT>. { } %% // c code..

Espero que ayude a alguien! Pelea

Quiero hacer una regla en flex para consumir un comentario de estilo c como / * * /

tengo el siguiente

c_comment "/*"[/n.]*"*/"

Pero nunca se hace coincidir. ¿Alguna idea de por qué? Si necesita más de mi código, por favor hágamelo saber y se lo enviaré todo. Gracias a cualquiera que responda.


Creo que esta solución es más simple:

"/*"((/*+[^/*])|([^*]))*/**"*/"


El ejemplo trabajado es:

///*([^*]|[/r/n]|(/*+([^*/]|[/r/n])))*/*+//

que se encuentra en ostermiller.org


Hay un ejemplo práctico en el manual de Flex , que hace que los casos de borde retorcido sean correctos:

<INITIAL>"/*" BEGIN(IN_COMMENT); <IN_COMMENT>"*/" BEGIN(INITIAL); <IN_COMMENT>[^*/n]+ // eat comment in chunks <IN_COMMENT>"*" // eat the lone star <IN_COMMENT>/n yylineno++;


He intentado varias de las soluciones sugeridas y aquí están los resultados.

  • No pude conseguir que la solución C_COMMENT, que tiene el mayor número de votos y se vea muy bien, funcione en la práctica (uno de los comentarios explica por lo menos una de las razones). Debe ser votado a la baja y, desde luego, no debe ser la solución más votada.
  • La solución de Mugen parecía funcionar en todo el código en el que lo ejecuté
  • No se pudo obtener la solución de Andrey para compilar en absoluto en lex. Miré el sitio web al que se hace referencia y el uso de patrones desde allí no ayudó
  • La respuesta de Paxdiablo funcionó y tuvo la ventaja de ser fácil de leer. Además modifiqué como sigue:

    "/*" { int c1 = 0, c2 = input(); for(;;) { if(c2 == EOF) break; if(c1 == ''*'' && c2 == ''/'') break; c1 = c2; c2 = input(); } }


Le sugiero que utilice las condiciones de inicio en su lugar.

%x C_COMMENT "/*" { BEGIN(C_COMMENT); } <C_COMMENT>"*/" { BEGIN(INITIAL); } <C_COMMENT>/n { } <C_COMMENT>. { }

Tenga en cuenta que no debe haber ningún espacio en blanco entre la <condition> y la regla.

%x C_COMMENT define el estado C_COMMENT, y la regla /* lo inicia. Una vez que se haya iniciado, */ hará que regrese al estado inicial ( INITIAL está predefinido), y todos los demás caracteres se consumirán sin ninguna acción en particular. Cuando dos reglas coinciden, Flex se desvigúa al tomar la que tiene la coincidencia más larga, por lo que la regla de puntos no impide que */ coincida. La regla /n es necesaria porque un punto coincide con todo excepto una nueva línea .

La definición %x hace que C_COMMENT sea un estado exclusivo , lo que significa que el lexer solo coincidirá con las reglas que están "etiquetadas" <C_COMMENT> una vez que ingrese al estado.

Aquí hay un pequeño ejemplo de lexer que implementa esta respuesta imprimiendo todo excepto lo que está dentro de /* comments */ .


No estoy seguro de por qué no se está recogiendo, pero sí sé que un patrón de ese tipo puede producir grandes elementos léxicos. Es más eficiente detectar solo el marcador de comentario de inicio y tirar todo en el bitbucket hasta que encuentre el marcador final.

Este sitio tiene un código que lo hará:

"/*" { for (;;) { while ((c = input()) != ''*'' && c != EOF) ; /* eat up text of comment */ if (c == ''*'') { while ((c = input()) == ''*'') ; if (c == ''/'') break; /* found the end */ } if (c == EOF) { error ("EOF in comment"); break; } } }


"/*"(.|/n)"*/" cambia tu expresión regular a esto, funcionará seguro.