2009-04-22 13 views
5

Ich habe ein Projekt für die Schule, wo wir Flex und Bison verwenden müssen. Ich möchte C++ verwenden, damit ich Zugriff auf STL und meine eigenen Klassen habe, die ich geschrieben habe. Wir waren mit dem folgenden Makefile zur Verfügung gestellt:Wie verwende ich C++ in Flex und 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 und parse.y haben einige anfängliche flex/Bison Sachen den Scanner und Parser zu erzeugen. Ich muss meinen Dateien eigene Dateien hinzufügen. symtab. {h, c} soll eine Implementierung einer Symboltabelle sein. attr. {h, c} sind für eine Attribut-Magie. Ich möchte symtab.c eine .cc-Datei machen, damit ich STL verwenden kann. Ich habe auch andere Gründe, C++ zu benutzen.

Ich habe versucht, eine parse.ypp-Datei zu verwenden, so dass eine CPP-Datei generiert werden würde. Aber das Problem ist, dass ich nicht die richtige .h-Datei bekomme. Ich änderte das Makefile wie folgt aussehen:

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 

Kann mir jemand sagen, was ich brauche C hinzuzufügen oder zu tun zu bekommen ++ zu arbeiten? Es sollte angemerkt werden, dass ich einige Sachen in der .y (oder .ypp) Datei hinzugefügt habe, um mit dem Verschieben von C nach C++ umzugehen. Insbesondere musste ich einige Sachen als extern deklarieren. Mein Hauptproblem ist, dass, wenn ich make ausführen, scan.l eine Reihe von Syntaxfehlern hat, und sie scheinen zu sein, weil es parse.tab.h nicht enthalten kann (weil es nie generiert wird).

+0

Für die Aufzeichnung flex das - + ++ oder Befehlszeilen-Flags --c eine C++ LEXER anstelle eines C eine zu erzeugen. Denken Sie darüber nach, obwohl ich nicht glaube, dass das Ihr Problem in diesem Fall ist. –

Antwort

3

Sie müssen nichts mit Flex oder Bison tun, um C++ zu verwenden, ich habe es oft getan. Sie müssen nur sicherstellen, dass Sie g ++ und nicht gcc verwenden.

Ihre Probleme sind mit dem Makefile, nicht mit dem Code.

+0

Ich akzeptiere das ziemlich spät: -) ... aber soweit ich mich erinnere, war das richtig und ich musste nur mit meinem Makefile herumspielen. Vielen Dank. – Tom

0

Verwenden Sie entweder einen C-Compiler oder einen C++ - Compiler, aber nicht beide (bis Sie wissen, was Sie tun). Sie sind sicher, sich selbst viele Male auf beiden Füßen zu schießen. Mischen von gcc und g ++ ist nicht gut.

Diese Linie ist verdächtig:

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

Auch Sie scheinen nicht CC überall zu verwenden, das unter Verwendung des Lebens gemacht hätte einfacher.

Angenommen, Sie ändern nicht eine einzige Zeile des C-Codes, werden Sie möglicherweise einige Fehler und einige Warnungen (wie veraltete Header usw.) treffen. Sie müssen sie auch reparieren.

-1

Wenn Sie Parser in C++ tun, würde ich empfehlen, Boost Spirit zu betrachten. Es ist so viel besser zu handhaben als Bison/Yacc.

Von here:

Geist ist ein objektorientierter rekursiv absteigende Parser-Generator Framework Vorlage Meta-Programmiertechniken implementiert. Expression-Templates erlauben es uns, die Syntax von Extended Backus-Normal Form (EBNF) vollständig in C++ zu approximieren.

+4

Ich stimme nicht zu.Ich habe beides versucht und ich mag Bison besser (obwohl ich ANTLR über beide bevorzuge). Die seltsame Syntax, die benötigt wird, um EBNF in C++ zu integrieren, macht es sehr schwer, Grammatiken zu lesen. – Zifre

+4

Keine Option in diesem Fall, da er Bison/Flex für sein Projekt verwenden muss. Außerdem muss nicht alles in C++ mit Boost erledigt werden. –

+3

Spirit ist eine der schlimmsten und übermäßig komplizierten C++ Bibliotheken auf dem Markt. Wenn überhaupt, ist es nichts anderes als ein wunderlicher Versuch zu sehen, welche Art von Operatoren man in C++ überladen kann. – Hippicoder

1

Es gibt einige Unterschiede, die Sie im Detail here überprüfen können.

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

Zum Beispiel für meine robots.txt flex-Parser, der mit scons gebaut, es ist so einfach wie: thisenv.CXXFile (target = 'Robots_flex.cc' source = 'robots.ll') Und Robots.cc Konstruktor hat: Roboter :: Roboter (std :: isotream *): yyFlexLexer (in, 0), [...] – piotr

Verwandte Themen