2009-11-18 34 views
9

Si olvido poner una línea vacía al final de cualquiera de mis archivos, mi programa obtiene un error de sintaxis. El problema es que mi gramática espera una nueva línea para finalizar la línea actual. Como no existe una nueva línea, bison genera un error de sintaxis porque no termina la regla.bison final del archivo

¿Cómo soluciono esto? Traté de hacer <<EOF>> devolver MY_EOF PERO cuando lo hago, Lex se bloquea una muerte horrible. Supongo que hay un código en su EOF predeterminado que no estoy llamando. No tengo idea de qué funciones pueden ser. El uso de EOF crear el error symbol EOF is used, but is not defined as a token and has no rules

Respuesta

14

Se puede usar un flex EOF regla para añadir una nueva línea a la entrada:

<<EOF>> { static int once = 0; return once++ ? 0 : '\n' } 
+1

Gran truco de magia, funciona para mí. – blueshift

+4

Tenga en cuenta que si desea hacer esto en un lector reentrante, en su lugar debe usar '{static int once = 0; volver (una vez =! una vez)? NEWLINE: 0; } 'dado que, de lo contrario, el primer archivo evitará que se reconozcan nuevas líneas en futuras invocaciones. –

+0

@ Hach-Que Buen punto - en ese caso, use: '{if (! Yyextra-> eof) {yyextra-> eof = true; regresar NEWLINE; } else {yyterminate(); }} 'y agrega un campo 'eof' a tu contexto. – nevelis

4

En el archivo de la lex

#define yyterminate() return token::END 

En el archivo de yacc

%token END 0 "end of file" 
+0

No he visto símbolo :: antes, se está utilizando la versión de C++? Tuve que cambiarlo para devolver MY_END pero% token MY_END 0 "fin del archivo", recibir la advertencia './test.y:90.11-75: advertencia: regla nunca reducida debido a conflictos: $ accept: programa" end of file "'. Parece que funciona, pero no estoy 100% seguro. –

+0

Sí, esa es la versión de C++. – DevDevDev

2

De hecho, para capturar el final del archivo en lex | flex puede usar el yywrap() función que es llamada por el analizador léxico si se alcanza el final del archivo de entrada.

esta solución está disponible tanto en lex como en flex. La devolución de llamada de yywrap() indica EOF para que pueda volver a implementar esta función e inyectar el trabajo que necesita hacer al final de su flujo de entrada.

+1

¿Escribió mal 'yywrap () ' – blueshift

+2

@blueshift No, no he escrito mal yywarp, es la macro, se llama automáticamente cuando llegamos al final del búfer en uso, regresa 1 cuando no hay búfer para leer o 0 si hay – Aymanadou

+3

Uso flex y tengo 'yywrap() 'pero no' yywarp() '. ¿Estás seguro? – blueshift

1

Anterior funciona bien para mí.

Si utiliza C Bizon (no en C++), acaba de uso final para Token :: END y en el archivo de yacc %token END

tenía otro problema después de que, si las macros no vuelven YY_NULL, nunca termina (bucle infinito)

se puede resolverse de esta manera:

bool term = false; 
#define yyterminate() return (term = !term)?END : YY_NULL 
Cuestiones relacionadas