Reputation: 13
I'm having trouble with compiling my flex and bison code. more specifically my parser.yy file. In this file I included MathCalc.h and BaseProg.h, which are classes I've made. The issue is when I instantiate the classes, it gives me a "multiple definition" error on compilation. Any help would be appreciated! Thank you!!
Parser.yy (snippet):
%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;
}
error:
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
Upvotes: 0
Views: 1789
Reputation: 241671
Any code in a %code requires
block will be placed both in the parser source file and in the parser header file. It's normal to #include
the parser header file in the scanner source (after all, that's why bison generates a header file), so it is unwise to put global variable definitions in a %code requires
block.
Indeed, it is always unwise to put global variable definitions in a header file, precisely because the header file is likely to be included in more than one source file, with the result that any global definitions (as opposed to declarations) will be inserted into more than one translation unit, violating the ODR.
For the header file, you should mark these objects (BaseProg bprog;
and MathCalc calc;
) as extern
, and then make sure you actually define them in some source file. Or, even better, you should avoid the use of globals in the first place.
Upvotes: 1