Ошибка Flex C ++ VTable - PullRequest
       66

Ошибка Flex C ++ VTable

0 голосов
/ 11 июля 2011

Я использую 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'

Вот весь соответствующий код:

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 определяет и конструктор, и деструктор. Кроме того, когда я пытаюсь перегрузить constr. и дестр. в Kraken.cc я получаю сообщение о том, что они «неявно определены».

Ответы [ 2 ]

0 голосов
/ 12 июля 2011

Попробуйте выполнить чистую перестройку (rm *.o) и перекомпилируйте. Компилятор должен генерировать этот материал автоматически. Некоторые компиляторы имеют специальную непереносимую магию , которая влияет на линковку виртуальной таблицы, но я не вижу ничего подобного в вашем коде.


Кроме того, в вашем make-файле я вижу, что вы написали правило для связи с g++, но вы не написали никакого правила для компиляции. Так что make использует свои встроенные правила, которые могут быть предоставлены компилятором C ++, предоставляемым вашей ОС, а не g++.

Другое дело, что правила makefile должны ставить первоисточник первым. Например:

неправильно:

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

право:

 KrakenScanner.o: KrakenScanner.cc KrakenScanner.hh

Наконец, объектные файлы не используются для создания других объектных файлов, только во время компоновки.

0 голосов
/ 11 июля 2011

Во-первых, это сообщение об ошибке от вашего компоновщика, а не от компилятора. Похоже, вы не ссылаетесь в KrakenScanner.o. Это также помогает применять demangler для вашего компилятора к выводу ошибок компилятора / компоновщика.

Какой компилятор вы используете?

...