Хотя вопросы «Неопределенная ошибка ссылки» задавались несколько раз, я не смог найти решение своей проблемы.
Я пытаюсь заставить 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 — Спецификация бизонов — генерирует 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)?
Если сгенерированный заголовочный файл точно соответствует указанному, т.е. extern "C"
тогда проблема, с которой вы можете столкнуться, состоит в том, что компилятор C будет генерировать неупорядоченный символ при компиляции функции, но компилятор C ++ будет генерировать зависимость от искаженного имени. Компоновщик увидит зависимость и символ, но не имея одно и то же имя, он не сможет сопоставить их вместе.
Взгляните на документацию по инструменту, используемому для генерации кода, и узнайте, как генерировать код, совместимый с C ++ (как правило, требуется просто включить дополнительный extern "C"
код в заголовках).
По поводу вашего error: undefined reference to 'yyerror(char const*)'
, вы можете прочитать документацию Bison, а более конкретно часть о йеррор. Это читает:
— 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
).
Ваши другие ошибки кажутся не связанными с Бизоном.
Изменить: о, вы, кажется, генерирует парсеры C, а не парсеры C ++. Ну, то же самое для синтаксических анализаторов C: yyerror предоставляется пользователем.
В простых программах достаточно следующего определения:
void
yyerror (char const *s)
{
fprintf (stderr, "%s\n", s);
}