Estoy tratando de analizar los comentarios de estilo C multilínea en mi flex (.l) Archivo:¿Por qué los comentarios multilínea en flex/bison son tan evasivos?
%s ML_COMMENT
%%
...
<INITIAL>"/*" BEGIN(ML_COMMENT);
<ML_COMMENT>"*/" BEGIN(INITIAL);
<ML_COMMENT>[.\n]+ { }
No estoy de devolver cualquier token y mi gramática (.y) no se refiere a los comentarios de cualquier manera.
Cuando ejecuto mi ejecutable, me sale un error de análisis:
$ ./a.out
/*
abc
def
Parse error: parse error
$ echo "/* foo */" | ./a.out
Parse error: parse error
(Mi función yyerror hace un printf ("Error de análisis:% s \ n"), que es donde la primera mitad de la mensaje de error redundante proviene de).
Puedo ver por qué el segundo ejemplo falla, ya que la totalidad de la entrada es un comentario, y dado que la gramática hace caso omiso de los comentarios, no hay enunciados. Por lo tanto, la entrada no es un programa válido. Pero la primera parte arroja un error de análisis antes de que termine el comentario.
también confuso:
$ ./a.out
/* foo */
a = b;
Parse error: parse error
En este caso, el comentario está cerrado antes de la entrada válida real (que, sin el comentario, analiza muy bien). El error ocurre realmente después de analizar "a", no después de intentar analizar la asignación "a = b;". Si ingreso "a" en su propia línea, aún arroja un error.
Dado que el mensaje de error es un error del analizador y no un error del escáner, ¿hay algo crucial que me falta en mi archivo .y? ¿O estoy haciendo algo mal en las reglas de mi escáner que se propaga al lado del analizador?
EDIT: por @ sugerencia de Rudi, que activó la depuración y encontró:
$ ./a.out
Starting parse
Entering state 0
Reading a token: /*
foo
Next token is 44 (IDENTIFER)
Shifting token 44 (IDENTIFER), Entering state 4
Reducing via rule 5 (line 130), IDENTIFER -> identifier
state stack now 0
Entering state 5
Apagué la depuración y se encontró que de hecho /* foo */ = bar;
analiza el mismo que foo = bar;
. Estoy usando flex 2.5.4; no me da ninguna advertencia sobre las reglas de estado que estoy tratando de usar.
I reetiquetado flexión a GNU-flex. Las reglas de su escáner se ven bien. El error de análisis indica una entrada de token no válida para el analizador. Es posible que desee publicar algunas reglas de Bison correspondientes. Además, puede ser una buena idea colocar las instrucciones printf() dentro de las reglas de bisonte, de esta manera puede ver qué reglas está intentando el analizador durante el escaneo del token. – Kizaru
También sería una buena idea crear un arnés de prueba separado para su escáner. De esta forma, puede aislar los defectos del escáner de los defectos del analizador. Cualquier sistema analizador-analizador es lo suficientemente complejo como para no necesitar inyectar complejidad adicional realizando pruebas de integración cuando lo que realmente desea es realizar pruebas de unidades ... – bstpierre
Cuando agrega el indicador '--debug' a su bisonte invoca y establece 'yydebug = 1' antes de la llamada' yyparse() ', luego el analizador emite información de depuración para cada token que ve desde el lexer. – Rudi