Múltiples analizadores flex / bison
-
06-07-2019 - |
Pregunta
¿Cuál es la mejor manera de manejar múltiples analizadores Flex / Bison dentro de un proyecto?
Escribí un analizador y ahora necesito otro 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 obtener es tener dos analizadores diferentes ( parser1.y
y parser2.y
) y poder usarlos desde una función externa (supongamos que < code> 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 de esta manera (evitando encapsular el analizador dentro de un objeto).
Solución
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 coherentes entre sí.
Otros consejos
Además de la respuesta de Leffler, me gustaría proporcionar otro enfoque aquí:
En el archivo .lex
puede usar % option prefix = " PREFIX "
, y en el archivo .y
puede usar % define api.prefix PREFIX
, que hace lo mismo que pasar -p PREFIX
a Bison y -P PREFIX
a Flex.
Observe que después de anular el prefijo predeterminado yy
, puede acceder a los nombres internos mediante AMBOS el yy *
original y su PREFIX *
anulado , aunque obviamente para nombres externos DEBE usar su PREFIX *
para acceder a ellos.
Si usa Bison 3.0 o superior, eche un vistazo a % define api.prefix {foo_}
, que reemplaza todos los yy
y YY
prefijos con foo_
y FOO_
.
Consulte Documentación sobre múltiples analizadores .
Entre Bison 2.6 y 3.0, solía no haber llaves: % define api.prefix foo_
.
La variable api.prefix ya no funciona para mí (está produciendo un error de compilación)
%define api.prefix {PREFIX}
Tuve que usar la siguiente sintaxis
%name-prefix="PREFIX"
Además de lo que ya se indicó, si usa un '% define api.prefix {PREFIX}' también cambiará el nombre de yytext & amp; & amp; yyparse a PREFIXtext y PREFIXparse. ¡No olvides el {} alrededor del prefijo!
Lo mismo se aplica a '% option prefix = " PREFIX "' en lex, su lexer cambiará de nombre a PREFIXlex.