ошибка сборки: неопределенная ссылка на `yyFlexLexer :: yyFlexLexer (std :: istream *, std :: ostream *) - PullRequest
0 голосов
/ 31 августа 2018

Я использовал Flex в своем приложении на машине с Windows, а компилятор - mingw32-make. Я получил ошибку сборки в коде C ++.

Я выполнил установку Flex и выполнил перенаправленный каталог include и lib на PATH.
Строка кода:

const char * filename;

std::fstream file;

file.open(filename, std::ios_base::in);

yyFlexLexer * scanner;

scanner = new yyFlexLexer(&file);

Ошибка:

"File.cpp:63: undefined reference to `yyFlexLexer::yyFlexLexer(std::istream*, std::ostream*)'"

Пожалуйста, помогите мне решить эту проблему.

Заранее спасибо!

1 Ответ

0 голосов
/ 01 сентября 2018
File.cpp:63: undefined reference to `yyFlexLexer::yyFlexLexer(std::istream*, std::ostream*)

Это означает, что ваш лексер c ++ либо не определен, либо определен под другим именем.

Вы не можете написать следующее, не скомпилировав и не связав гибкий файл:

#include <fstream>
#include <FlexLexer.h>
int main()
{
  const char * filename= "file.txt";;
  std::fstream file;
  file.open(filename, std::ios_base::in);

  // better use auto scanner = std::make_unique<yyFlexLexer>(&file)
  yyFlexLexer * scanner; 
  // leaks memory
  scanner = new yyFlexLexer(&file);
}

Вышеописанное не будет работать без написания файла flex, запуска flex (который по умолчанию генерирует lex.yy.cc), а затем компиляции и компоновки сгенерированного кода. Вы можете прочитать все об этом в Создание сканеров C ++ .

Если вы скомпилировали и связали сгенерированный код, вы все равно можете получить эту ошибку, если был создан именованный сканер. По сути, если ваша программа имеет более одного сканера, правильное решение - дать разные имена разным сканерам. В этом случае вам нужно получить правильное имя.

Это все в руководстве по флексу, в разделе Создание сканеров C ++ . Который я цитирую здесь:

Если вы хотите создать несколько (разных) классов лексеров, вы используете флаг `-P '(или опция` prefix =') для переименования каждого yyFlexLexer в какой-то другой xxFlexLexer. Затем вы можете включить ` 'в ваш другие источники один раз для каждого класса лексера, сначала переименовав yyFlexLexer в следующим образом:

#undef yyFlexLexer 
#define yyFlexLexer xxFlexLexer 
#include <FlexLexer.h> 

#undef yyFlexLexer   
#define yyFlexLexer zzFlexLexer   
#include <FlexLexer.h> 

если, например, вы использовали `% option prefix =" xx "'для одного из ваших сканеры и `% option prefix =" zz "'для других.

Это уродливо и хитро, но именно так flex работает с C ++. Это было задокументировано как экспериментальное с 90-х или раньше. Я предполагаю, что это не изменится.

...