我在编译我的flex和bison代码时遇到了麻烦。更具体地说,我的parser.yy文件。在这个文件中,我包括MathCalc.h和BaseProg.h,它们是我已经制作的类。问题是当我实例化类时,它给了我一个多重定义"编译错误。任何帮助,将不胜感激!谢谢!!
Parser.yy(摘录):
%code requires {
#include <iostream>
#include <cmath>
#include "MathCalc.h"
#include "BaseProg.h"
/* Parser error reporting routine */
void yyerror(const char *msg);
/* Scannar routine defined by Flex */
int yylex();
using namespace std;
BaseProg bprog;
MathCalc calc;
enum Type { INT, FLT};
}
/* yylval union type */
%union {
double dval;
int ival;
char* name;
Type type;
}
错误:
bison -d parser.yy
g++ -c -o scanner.o scanner.cc
g++ -c -o parser.tab.o parser.tab.cc
g++ scanner.o parser.tab.o BaseProg.o MathCalc.o -lfl -o ../Proj2
parser.tab.o:(.bss+0x0): multiple definition of `bprog'
scanner.o:(.bss+0x28): first defined here
parser.tab.o:(.bss+0x1): multiple definition of `calc'
scanner.o:(.bss+0x29): first defined here
collect2: ld returned 1 exit status
答案 0 :(得分:1)
%code requires
块中的任何代码都将放在解析器源文件和解析器头文件中。扫描仪源中的解析器头文件#include
是正常的(毕竟,这是bison生成头文件的原因),因此将全局变量定义放在{{{1}中是不明智的1}}阻止。
实际上,将全局变量定义放在头文件中总是不明智的,因为头文件可能包含在多个源文件中,结果是任何全局定义(与声明相反)都将被插入多个翻译单元,违反了ODR。
对于头文件,您应将这些对象(%code requires
和BaseProg bprog;
)标记为MathCalc calc;
,然后确保在某些源文件中实际定义它们。或者,更好的是,你应该首先避免使用全局变量。