2009-04-22 28 views
5

Tengo un proyecto para la escuela donde tenemos que usar flex y bison. Quiero usar C++ para tener acceso a STL y mis propias clases que escribí. Nos dieron con el siguiente Makefile:¿Cómo uso C++ en flex y bison?

CC = gcc 
CFLAGS = -g 

OBJs = parse.tab.o symtab.o attr.o lex.yy.o 

default: parser 

parser: ${OBJs} 
    ${CC} ${CFLAGS} ${OBJs} -o parser -lfl 

lex.yy.c: scan.l parse.tab.h attr.h 
    flex -i scan.l 

parse.tab.c: parse.y attr.h symtab.h 
    bison -dv parse.y 

parse.tab.h: parse.tab.c 

clean: 
    rm -f parser lex.yy.c *.o parse.tab.[ch] parse.output 

depend: 
    makedepend -I. *.c 

scan.l y parse.y tienen cierta flexibilidad material inicial/bisontes para generar el escáner y el analizador. Necesito agregar mis propias cosas a esos archivos. symtab. {h, c} se supone que es una implementación de una tabla de símbolos. attr. {h, c} son para algunos atributos mágicos. Quiero hacer que symtab.c sea un archivo .cc para poder usar STL. También tengo otras razones para querer usar C++.

Intenté utilizar un archivo parse.ypp, para que se generara un archivo .cpp. Pero el problema es que no estoy obteniendo el archivo .h correcto. He cambiado el Makefile para tener este aspecto:

CC = g++   # Change gcc to g++ 
CFLAGS = -g 

OBJs = lex.yy.o parse.tab.o symtab.o attr.o 

default: lex.yy.c parser # added lex.yy.c so I could just keep lex stuff in C since I don't really need C++ there 

parser: ${OBJs} 
    ${CC} ${CFLAGS} ${OBJs} -o parser -lfl 

lex.yy.o: scan.l parse.tab.h attr.h  # added this rule to use gcc instead of g++ 
    gcc -c -o lex.yy.o lex.yy.c 

lex.yy.c: scan.l parse.tab.h attr.h 
    flex -i scan.l 

parse.tab.cpp: parse.ypp attr.h symtab.h 
    bison -dv parse.ypp 

parse.tab.h: parse.tab.cpp  # I want a parse.tab.h but I get parse.tab.hpp 

clean: 
    rm -f parser lex.yy.c *.o parse.tab.cpp parse.tab.h parse.output 

depend: 
    makedepend -I. *.c 

Puede alguien decirme lo que tengo que añadir o hacer para conseguir C++ de trabajo? Cabe señalar que agregué algunas cosas en el archivo .y (o .ypp) para tratar de pasar de C a C++. En particular, tuve que declarar algunas cosas como externas. Mi problema principal es que cuando ejecuto make, scan.l tiene un montón de errores de sintaxis, y parecen ser porque no puede incluir parse.tab.h (porque nunca se genera).

+0

Para el registro, flex tiene los indicadores de línea de comandos - + o --C++ para generar un lector de C++ en lugar de uno de C. Considera investigar eso, aunque no creo que ese sea tu problema en este caso. –

Respuesta

3

No necesita hacer nada con flex o bison para usar C++, lo he hecho muchas veces. Solo tienes que asegurarte de usar g ++, no gcc.

Sus problemas son con el archivo MAKE, no el código.

+0

Aceptando esto bastante tarde: -) ... pero cuando recuerdo esto era correcto y solo necesitaba jugar con mi archivo MAKE. Gracias. – Tom

0

Utilice un compilador C o un compilador C++ pero no ambos (hasta que sepa lo que está haciendo). De lo contrario, te dispararás muchas veces con los dos pies. Mezclar gcc y g ++ no es bueno.

Esta línea es sospechoso:

lex.yy.o: scan.l parse.tab.h attr.h  # added this ... 
gcc -c -o lex.yy.o lex.yy.c 

Además, no parece estar utilizando CC en cualquier lugar, usando que lo habría hecho la vida más fácil.

Suponiendo que no se cambia una sola línea del código C, es posible que se produzcan algunos errores y bastantes advertencias (como encabezados obsoletos, etc.). Tendrás que arreglarlos también.

-1

Si está haciendo analizadores sintácticos en C++, le recomendaría mirar Boost Spirit. Es mucho más fácil de manejar que bison/yacc.

De here:

Espíritu es un marco generador de análisis sintáctico descendente recursivo orientado a objetos implementado utilizando técnicas de meta-programación de la plantilla. Las plantillas de expresión nos permiten aproximarnos por completo a la sintaxis del Backus-Normal Form (EBNF) extendido en C++.

+4

No estoy de acuerdo.He probado ambos y me gusta más el bisonte (aunque prefiero ANTLR sobre ambos). La extraña sintaxis necesaria para ajustar EBNF en C++ hace que sea muy difícil leer gramáticas. – Zifre

+4

No es una opción en este caso, ya que tiene que usar bison/flex para su proyecto. Además, no todo en C++ debe hacerse con Boost. –

+3

Spirit es una de las bibliotecas de C++ peores y más complicadas que existen. En todo caso, no es más que un intento caprichoso de ver qué tipo de operadores se puede sobrecargar en C++. – Hippicoder

1

Existen algunas diferencias que puede consultar en detalle here.

4
For using flex with C++: 
1: read the flex docs: 
2: use flex -+ -o file.cc parser.ll 
3: In the .ll file: 

%option c++ 
%option yyclass="Your_class_name" 
%option batch 

4: In your .hh file, derive Your_class_name from public yyFlexLexer 
5: you can then use your_class_instance.yylex() 
+0

Por ejemplo, para mi robots.txt flex parser que está construido con scons es tan simple como: thisenv.CXXFile (target = 'Robots_flex.cc', source = 'robots.ll') Y Robots.cc constructor tiene: Robots :: Robots (std :: istream * en): yyFlexLexer (en, 0), [...] – piotr

Cuestiones relacionadas