2011-07-10 66 views
0

我正在使用Flex和Bison創建一個編譯器。正如我試圖爲我的程序創建一個AST(抽象語法樹),我需要將它移植到C++。到目前爲止,我已經成功了,直到從我的編譯器遇到了一個相當模糊的錯誤:Flex C++ VTable錯誤

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'

這裏是所有相關代碼:

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` 

我不知道這是否會幫助,但FlexLexer.h定義的類FlexLexer和yyFlexLexer。 FlexLexer只聲明一個虛擬析構函數,而yyFlexLexer則定義了構造函數和析構函數。此外,當我試圖超載建設。和destr。在Kraken.cc中,我收到一個錯誤,說這兩個是「隱式定義的」。

+0

您不應該將目標文件放在makefile規則中進行編譯,只能用於鏈接。 –

回答

0

嘗試一個乾淨的重建(rm *.o)並重新編譯。編譯器應該自動生成這些東西。一些編譯器有special non-portable magic影響v表連接,但我沒有看到你的代碼中的任何東西。


而且,我看到你的makefile你寫的規則與g++鏈接,但你沒有寫編譯任何規則。因此make正在使用其內置規則,可能由您的操作系統提供的C++編譯器,而不是g++

另一件事是makefile規則應該把主要來源放在第一位。例如:

錯誤:

KrakenScanner.o: KrakenScanner.hh KrakenScanner.cc parser.o 

權:

KrakenScanner.o: KrakenScanner.cc KrakenScanner.hh 

最後,文件不會被用於構建其他目標文件對象,只有在連接時。

+0

執行完指令後,我收到與以前相同的錯誤。 – singerng

+0

@user:增加了一些更多的想法。 –

0

首先,錯誤信息來自您的鏈接器,而不是您的編譯器。它看起來像你沒有鏈接KrakenScanner.o。它還有助於將編譯器的名稱demangler應用於編譯器/鏈接器錯誤輸出。

你使用什麼編譯器?

+0

demangler這個名字給了我Kraken :: FlexScanner :: FlexScanner()和Kraken :: FlexScanner ::〜FlexScanner()。 – singerng