2009-10-28 18 views
5

¿Cuál es la mejor manera de manejar múltiples analizadores Flex/Bison dentro de un proyecto?Analizadores múltiples de flex/bison

Escribí un analizador y ahora necesito un segundo en el mismo proyecto. Hasta ahora en la tercera sección de parser1.y inserté el método main(..) y llamé yyparse desde allí.

Lo que quiero conseguir es tener dos analizadores diferentes (parser1.y y parser2.y) y ser capaz de utilizarlas de una función externa (vamos a suponer main en main.cpp).

¿Qué precauciones debo usar para exportar las funciones yyparse fuera de los archivos .y y cómo debo manejar dos analizadores?

PS. Estoy usando g ++ para compilar, pero no las versiones C++ de Flex y Bison, y me gustaría mantenerlo así (evitando así encapsular el analizador dentro de un objeto).

Respuesta

7

Tenga en cuenta que Bison proporciona la opción '-p zz' para prefijar símbolos con 'zz' en lugar de 'yy'.

Del mismo modo, Flex proporciona la opción '-P zz' para prefijar símbolos con 'zz' en lugar de 'yy'. Utiliza '-p' para informes de rendimiento. 'Es una pena que no sean consistentes entre sí.

+0

Cuando hago esto, mi lexer y analizador tienen muchas referencias a YYTYPE y YYSTYPE, etc. y la compilación falla. ¿Por qué no se están convirtiendo esos? ¿¿Qué estoy haciendo mal?? No quiero un analizador de reentrada, solo quiero un analizador de una sola vez que invoque a uno de los dos analizadores, luego el programa se cierra. – TimeHorse

+0

@ TimeHorse: dada la cantidad de tiempo entre la respuesta a esta pregunta y su comentario/pregunta, creo que debería hacer una nueva pregunta, ilustrando el problema que tiene con dos pequeños ejemplos de lexer/gramática (un MCVE - [MCVE ]) y muestra el proceso de compilación que estás usando y los mensajes de error que recibes. Sin que aproveches la oportunidad para proporcionar esa información, que obtienes con una nueva pregunta, realmente no puedo dar una respuesta. De todos modos regrese y deje un comentario aquí pidiéndome que mire su nueva pregunta; considere incluir un enlace a esta pregunta en la suya también. –

10

Además de la respuesta de Leffler, me gustaría ofrecer otro enfoque aquí:

En el archivo .lex podría utilizar %option prefix="PREFIX", y en el archivo .y se podría utilizar %define api.prefix PREFIX, que hace lo mismo que pasa -p PREFIX a Bison y -P PREFIX a Flex.

Aviso después de la anulación del prefijo predeterminado yy, se puede acceder a través de nombres internos tanto el original y su yy* anulado PREFIX*, mientras que, obviamente, para los nombres externos deberá utilizar su PREFIX* para acceder a ellos.

+0

Tenga en cuenta que en las versiones modernas de bison necesita hacer '% define api.prefix {PREFIX}' o recibe una advertencia –

5

Si utiliza bisonte 3.0 o mejor, a continuación, echar un vistazo a %define api.prefix {foo_}, que sustituye a todos los yy y YY prefijos con foo_ y FOO_.

Ver el Documentation about Multiple Parsers.

Entre Bison 2.6 y 3.0, solía haber llaves: %define api.prefix foo_.

-1

Además de lo que ya se ha dicho, si se utiliza un '% define api.prefix {prefix}' también cambiará el nombre de yytext & & yyparse a PREFIXtext y PREFIXparse. ¡No olvide el {} alrededor del prefijo!
Lo mismo se aplica a '% option prefix = "PREFIX"' en lex, su lexer se renombrará a PREFIXlex.

Cuestiones relacionadas