Невизначене посилання на yywrap


82

У мене є проста "мова", я використовую Flex (лексичний аналізатор), це так:

/* Just like UNIX wc */
%{
int chars = 0;
int words = 0;
int lines = 0;
%}

%%
[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n        { chars++; lines++; }
.         { chars++; }
%%

int main()
{
    yylex();
    printf("%8d%8d%8d\n", lines, words, chars);
}

Якщо я запускаю a flex count.l, все проходить нормально без помилок або попереджень, то при спробі зробити a cc lex.yy.cя отримую такі помилки:

ubuntu @ eeepc: ~ / Desktop $ cc lex.yy.c
/tmp/ccwwkhvq.o: У функції yylex': lex.yy.c:(.text+0x402): undefined reference toyywrap '
/tmp/ccwwkhvq.o: У функції input': lex.yy.c:(.text+0xe25): undefined reference toyywrap'
collect2: ld повернуто 1 статус виходу

Що не так?

Відповіді:


126

Сканер викликає цю функцію в кінці файлу, тому ви можете направити її на інший файл і продовжити сканування його вмісту. Якщо вам це не потрібно, використовуйте

%option noyywrap

у специфікації сканера.

Незважаючи на те, що відключення yywrap , безумовно, є найкращим варіантом, можливо, можливо буде встановити зв’язок, -lflщоб використовувати функцію за замовчуванням yywrap()у бібліотеці fl(тобто libfl.a), надану flex. Posix вимагає, щоб бібліотека була доступна з прапором компонувальника, -llа за замовчуванням установка OS X надає лише це ім’я.


1
Де саме потрібно додати "% option noyywrap", будь ласка? У розділі визначення чи в командному рядку?
yamex5

Я додав його на початок .lфайлу і lexприйняв! Я не впевнений, що це найкраще місце. Можливо, це не має значення.
Діпак,

9

Я вважаю за краще визначати власний yywrap (). Я компілюю з C ++, але суть має бути очевидною. Якщо хтось викликає компілятор із кількома вихідними файлами, я зберігаю їх у списку або масиві, а потім у кінці кожного файлу викликається yywrap (), щоб дати вам можливість продовжити роботу з новим файлом.

int yywrap() {
   // open next reference or source file and start scanning
   if((yyin = compiler->getNextFile()) != NULL) {
      line = 0; // reset line counter for next source file
      return 0;
   }
   return 1;
}

3

flex не завжди встановлюється зі своїми бібліотеками розробки (що дивно, оскільки це інструмент розробки). Встановіть бібліотеки, і життя стане кращим.

На базових системах Redhat:

yum -y install flex-devel
./configure && make

На системах на базі Debian

sudo apt-get install libfl-dev

2

Як примітка для послідовників, у flex 2.6.3 є помилка, де libfl.a "зазвичай" визначає yywrap, але потім у певних випадках цього не робить, тому перевірте, чи це ваша версія flex, може бути пов'язана з вашою проблемою:

https://github.com/westes/flex/issues/154


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.