7

我有一个学校项目,我们需要使用 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(因为它永远不会生成)。

4

5 回答 5

9

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

您的问题在于 Makefile,而不是代码。

于 2009-04-22T18:22:02.610 回答
5
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()
于 2009-04-23T05:26:34.260 回答
1

您可以在此处详细查看其中的一些差异 。

于 2009-04-23T03:29:23.573 回答
0

使用 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 代码的任何一行,您可能会遇到一些错误和相当多的警告(如已弃用的标头等)。您还必须修复它们。

于 2009-04-22T18:01:49.927 回答
-3

如果您正在使用 C++ 进行解析器,我建议您查看Boost Spirit。它比 bison/yacc 好用得多。

这里

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

于 2009-04-22T18:54:03.377 回答