I am using Flex and Bison to create a compiler. As I am trying to create an AST (Abstract Syntax Tree) for my program, I need to port it to C++. So far I have been successful, until a encountered a rather obscure error from my compiler:
Kraken.o: In function Kraken::FlexScanner::FlexScanner()':
Kraken.cc:(.text._ZN6Kraken11FlexScannerC2Ev[_ZN6Kraken11FlexScannerC5Ev]+0x26): undefined reference to vtable for Kraken::FlexScanner'
Kraken.o: In function Kraken::FlexScanner::~FlexScanner()':
Kraken.cc:(.text._ZN6Kraken11FlexScannerD2Ev[_ZN6Kraken11FlexScannerD5Ev]+0xb): undefined reference to vtable for Kraken::FlexScanner'
Here is all the relevant code:
Kraken.cc:
#include "KrakenScanner.hh"
#include "KrakenParser.hh"
int main(int argc, char * argv[]) {
Kraken::Parser parser;
return parser.parse();
}
KrakenScanner.hh:
#ifndef KRAKENSCANNER_HH_
#define KRAKENSCANNER_HH_
#if ! defined(yyFlexLexerOnce)
#include <FlexLexer.h>
#endif
#undef YY_DECL
#define YY_DECL int Kraken::FlexScanner::yylex()
#include "parser.hh"
namespace Kraken {
class FlexScanner : public yyFlexLexer {
public:
int yylex(Kraken::BisonParser::semantic_type* lval);
private:
int yylex();
Kraken::BisonParser::semantic_type* yylval;
};
}
#endif /* KRAKENSCANNER_HH_ */
KrakenScanner.cc:
#include "KrakenScanner.hh"
int Kraken::FlexScanner::yylex(Kraken::BisonParser::semantic_type* lval) {
yylval = lval; return yylex();
}
Makefile:
OBJS := Kraken.o parser.o scanner.o KrakenScanner.o KrakenParser.o
%.cc: %.y
bison -o $(@:%.o=%.d) $<
%.cc: %.l
flex -o$(@:%.o=%.d) -i $<
all: $(OBJS)
g++ -okraken $(OBJS)
Kraken.o: Kraken.cc KrakenScanner.o KrakenParser.o
KrakenScanner.o: KrakenScanner.hh KrakenScanner.cc parser.o
parser.o: parser.hh parser.cc
parser.cc: parser.y
scanner.o: scanner.cc
scanner.cc: scanner.l
KrakenParser.o: KrakenParser.hh KrakenParser.cc KrakenScanner.o`
I don’t know if this will help, but FlexLexer.h defines the classes FlexLexer and yyFlexLexer. FlexLexer declares just a virtual destructor, and yyFlexLexer defines both a constructor and destructor. Also, when I attempt to overload the constr. and destr. in Kraken.cc, I get an error saying that the two are “implicitly defined”.
Try a clean rebuild (
rm *.o) and recompile. The compiler is supposed to generate this stuff automatically. Some compilers have special non-portable magic to influence v-table linking, but I don’t see anything like that in your code.Also, I see in your makefile that you’ve written a rule for linking with
g++, but you haven’t written any rule for compilation. Somakeis using its built-in rules, which might by the C++ compiler provided by your OS, notg++.Another thing is that makefile rules should put the primary source first. For example:
wrong:
right:
Finally, object files aren’t used to build other object files, only during linking.