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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/778431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:14:57  来源:igfitidea点击:

How do I use C++ in flex and bison?

c++cbisonflex-lexer

提问by Tom

I have a project for school where we need to use flex and bison. I want to use C++ so that I have access to STL and my own classes that I wrote. We were provided with the following Makefile:

我有一个学校项目,我们需要使用 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 and parse.y have some initial flex/bison stuff to generate the scanner and parser. I need to add my own stuff to those files. symtab.{h, c} is supposed to be a implementation of a symbol table. attr.{h, c} are for some attribute magic. I want to make symtab.c a .cc file so I can use STL. I also have other reasons for wanting to use C++.

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

I tried to use a parse.ypp file, so that a .cpp file would be generated. But the problem is that I'm not getting the right .h file. I changed the Makefile to look like this:

我尝试使用 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

Can someone tell me what I need to add or do to get C++ working? It should be noted I added some stuff in the .y (or .ypp) file to deal with moving from C to C++. In particular, I had to declare some stuff as extern. My main problem is that when I run make, scan.l has a bunch of syntax errors, and they seem to be because it cannot include parse.tab.h (because it is never generated).

有人能告诉我我需要添加什么或做什么才能让 C++ 工作吗?应该注意的是,我在 .y(或 .ypp)文件中添加了一些内容来处理从 C 到 C++ 的迁移。特别是,我必须将一些东西声明为 extern。我的主要问题是当我运行 make 时,scan.l 有一堆语法错误,它们似乎是因为它不能包含 parse.tab.h(因为它从未生成)。

回答by Zifre

You don't need to do anything with flex or bison to use C++, I have done it many times. You just have to make sure you use g++, not gcc.

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

Your problems are with the Makefile, not the code.

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

回答by piotr

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

回答by justinhj

There are some differences that you can check out in detail here.

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

回答by dirkgently

Use either a C Compiler or a C++ compiler but not both (till you know what you are upto). You are sure to shoot yourself many times on both your feet otherwise. Mixing gcc and g++ isn't good.

使用 C 编译器或 C++ 编译器,但不要同时使用两者(直到您知道自己在做什么)。否则,您肯定会用双脚向自己射击很多次。混合使用 gcc 和 g++ 并不好。

This line is suspect:

这条线是可疑的:

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

Also, you don't seem to be using CCanywhere, using that'd have made life easier.

此外,您似乎没有在CC任何地方使用,使用它会使生活更轻松。

Assuming you don't change a single line of the C code, you will possibly hit some errors and quite a few warnings (like deprecated headers etc). You'll have to fix them as well.

假设您不更改单行 C 代码,您可能会遇到一些错误和相当多的警告(如已弃用的标头等)。你也必须修复它们。

回答by lothar

If you are doing parsers in C++ I would recommend to look at Boost Spirit. It is so much nicer to handle than bison/yacc.

如果您使用 C++ 进行解析器,我建议您查看Boost Spirit。它比野牛/yacc 更好处理。

From here:

这里

Spirit is an object-oriented recursive-descent parser generator framework implemented using template meta-programming techniques. Expression templates allow us to approximate the syntax of Extended Backus-Normal Form (EBNF) completely in C++.

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