如何在flex和bison中使用C ++?

我有一个学校项目,我们需要使用flex和bison。 我想使用C ++,以便我可以访问我编写的STL和我自己的类。 我们获得了以下Makefile:

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和parse.y有一些初始的flex / bison东西来生成扫描器和解析器。 我需要将自己的东西添加到这些文件中。 symtab。{h,c}应该是符号表的实现。 attr。{h,c}用于某些属性魔法。 我想制作symtab.ca .cc文件,以便我可以使用STL。 我还有其他原因想要使用C ++。

我尝试使用parse.ypp文件,以便生成.cpp文件。 但问题是我没有得到正确的.h文件。 我将Makefile更改为如下所示:

 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 

有人可以告诉我我需要添加或做什么来让C ++工作吗? 应该注意我在.y(或.ypp)文件中添加了一些东西来处理从C到C ++的转换。 特别是,我不得不宣布一些东西为extern。 我的主要问题是,当我运行make时,scan.l有一堆语法错误,它们似乎是因为它不能包含parse.tab.h(因为它永远不会生成)。

使用C ++你不需要使用flex或bison做任何事情,我已经多次完成了。 你只需要确保使用g ++,而不是gcc。

你的问题是Makefile,而不是代码。

 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() 

您可以在此处详细了解一些差异。

使用C编译器或C ++编译器,但不能同时使用(直到您知道自己的要求)。 你肯定会在你的双脚上多次射击自己。 混合gcc和g ++并不好。

这条线是可疑的:

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

此外,你似乎没有在任何地方使用CC ,使用它已经让生活更轻松。

假设你没有改变C代码的一行,你可能会遇到一些错误和一些警告(比如弃用的标题等)。 你也必须修复它们。

如果你在C ++中使用解析器,我建议你看一下Boost Spirit 。 处理比bison / yacc好得多。

从这里 :

Spirit是一个面向对象的递归 – 下降解析器生成器框架,使用模板元编程技术实现。 表达式模板允许我们在C ++中完全逼近扩展的Backus-Normal Form(EBNF)的语法。