2

「未定義の参照エラー」という質問が何度か寄せられましたが、問題の解決策が見つかりませんでした。

flex と bison を Qt アプリで動作させようとしています。リンクのみで問題に直面しています。

これらは関連ファイルです-

1) icd.l - Lex 仕様書 - iclexer.cを生成し、関数の定義を含む-

void yyerror(char const *s){...}
void* setUpBuffer(char const* text){...}
void tearDownBuffer(void* buffer){...}
int nextToken(){...}

2) iclexer.h

#ifndef ICLEXER_H
#define ICLEXER_H

extern void  yyerror(char const *);
extern int   yylex();
extern char* yytext;
extern void* setUpBuffer(char const* text);
extern void  tearDownBuffer(void* buffer);
extern int nextToken();

#endif // ICLEXER_H

3) icparser.h

#ifndef ICPARSER_H
#define ICPARSER_H
#include "iclexer.h"
#include <string>

extern void initLexer(std::string const& t);
extern void clearLexer();
extern int yyparse();

class Parser
{
public:
    Parser(std::string const& s)
    {
        initLexer(s);
    }
    void parse()
    {
        yyparse();
    }
    ~Parser()
    {
        clearLexer();
    }
};
#endif // ICPARSER_H

4) icd.y - Bison 仕様 - icparser.cppを生成し、関数の定義を含む-

void initLexer(std::string const& t);
void clearLexer();
int yylex();

私の GUI コードでは、icparser.hをインクルードし、 のインターフェイスを使用していclass Parserます。しかし、次のエラーが発生します-

/home/vinayak/codes/qt/dic_sim/icparser.cpp:1402:
エラー: 「yyerror(char const*)」への未定義の参照

setUpBuffer(char const* text);tearDownBuffer(void* buffer);およびについても同様のエラーが発生しnextToken();ます。基本的に、iclexer.cの関数が正しくリンクされていません。

このコードを変更する方法、または Qt (Qt Creator) でリンク順序を変更する方法を教えてください。

4

2 に答える 2

2

生成されたヘッダー ファイルが記述どおりである場合、つまり何もextern "C"ない場合に直面する可能性のある問題は、関数のコンパイル時に C コンパイラがマングルされていないシンボルを生成するが、C++ コンパイラがマングルされた名前への依存関係を生成することです。リンカーは依存関係とシンボルを認識しますが、同じ名前を持っていないと、それらを一緒に一致させることができません。

コードの生成に使用されたツールのドキュメントを見て、C++ 互換コードを生成する方法を見つけてください (通常はextern "C"、ヘッダーに余分なコードを含める必要があります)。

于 2013-01-23T16:27:44.830 に答える
2

についてerror: undefined reference to 'yyerror(char const*)'は、Bison のドキュメント、より具体的には yyerror に関する部分を読みたいと思うかもしれません。それは読みます:

— Method on parser: void error (const location_type& l, const std::string& m)

The definition for this member function must be supplied by the user: the parser
uses it to report a parser error occurring at l, described by m.

この定義は、おそらくコードにありません。yyerror実際yy::parser::errorにはyy::、パーサーのデフォルトの名前空間 ( で変更可能%define namespace "foo") とparser::パーサー クラスのデフォルト名 ( で変更可能) を持つことに注意してください%define parser_class_name foo

あなたの他のエラーは Bison とは無関係のようです。

編集: ああ、C++ パーサーではなく、C パーサーを生成しているようです。C パーサーでも同じです: yyerror は user-suppliedです。

単純なプログラムでは、次の定義で十分です。

 void
 yyerror (char const *s)
 {
   fprintf (stderr, "%s\n", s);
 }
于 2013-01-24T09:30:03.260 に答える