【问题标题】:Flex C++ VTable ErrorFlex C++ VTable 错误
【发布时间】:2011-07-10 21:50:25
【问题描述】:

我正在使用 Flex 和 Bison 创建编译器。当我试图为我的程序创建一个 AST(抽象语法树)时,我需要将它移植到 C++。到目前为止我已经成功了,直到我的编译器遇到了一个相当模糊的错误:

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'

以下是所有相关代码:

海妖.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();
}

生成文件:

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 定义了构造函数和析构函数。另外,当我尝试重载 constr.和破坏。在 Kraken.cc 中,我收到一条错误消息,指出这两者是“隐式定义的”。

【问题讨论】:

  • 你不应该将目标文件放在你的 makefile 规则中进行编译,只用于链接。

标签: parsing virtual flex-lexer lexical-analysis vtable


【解决方案1】:

尝试干净的重建 (rm *.o) 并重新编译。编译器应该自动生成这些东西。一些编译器有 special non-portable magic 来影响 v-table 链接,但我在你的代码中没有看到类似的东西。


另外,我在您的 makefile 中看到您编写了与 g++ 链接的规则,但您没有编写任何编译规则。所以make 正在使用它的内置规则,这可能是由你的操作系统提供的 C++ 编译器,而不是g++。

另一件事是,makefile 规则应该将主要来源放在首位。例如:

错误:

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

右:

 KrakenScanner.o: KrakenScanner.cc KrakenScanner.hh

最后,目标文件不用于构建其他目标文件,仅在链接期间。

【讨论】:

  • 执行您的指令后,我遇到了与以前相同的错误。
  • @user:添加了更多想法。
【解决方案2】:

首先,该错误消息来自您的链接器,而不是您的编译器。看起来您没有在 KrakenScanner.o 中进行链接。它还有助于将编译器的名称 demangler 应用于编译器/链接器错误输出。

你用的是什么编译器?

【讨论】:

  • 这个名字 demangler 刚刚给了我 Kraken::FlexScanner::FlexScanner() 和 Kraken::FlexScanner::~FlexScanner()。
猜你喜欢
  • 2013-02-22
  • 2014-10-12
  • 1970-01-01
  • 2016-10-25
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多