多个定义?

时间:2015-03-03 04:49:43

标签: c++ parsing bison yacc flex-lexer

我在编译我的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

1 个答案:

答案 0 :(得分:1)

%code requires块中的任何代码都将放在解析器源文件和解析器头文件中。扫描仪源中的解析器头文件#include是正常的(毕竟,这是bison生成头文件的原因),因此将全局变量定义放在{{{1}中是不明智的1}}阻止。

实际上,将全局变量定义放在头文件中总是不明智的,因为头文件可能包含在多个源文件中,结果是任何全局定义(与声明相反)都将被插入多个翻译单元,违反了ODR。

对于头文件,您应将这些对象(%code requiresBaseProg bprog;)标记为MathCalc calc;,然后确保在某些源文件中实际定义它们。或者,更好的是,你应该首先避免使用全局变量。