Niezdefiniowane odniesienie do yywrap

82

Mam prosty „język”, w którym używam Flex (Lexical Analyzer), wygląda to tak:

/* 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);
}

Uruchamiam a flex count.l, wszystko idzie dobrze bez błędów i ostrzeżeń, to jak próbuję zrobić a cc lex.yy.cwyskakuje mi ten błąd:

ubuntu @ eeepc: ~ / Desktop $ cc lex.yy.c
/tmp/ccwwkhvq.o: W funkcji yylex': lex.yy.c:(.text+0x402): undefined reference toyywrap '
/tmp/ccwwkhvq.o: W funkcji input': lex.yy.c:(.text+0xe25): undefined reference toyywrap'
collect2: ld zwrócił 1 status wyjścia

Co jest nie tak?

Nathan Campos
źródło

Odpowiedzi:

126

Skaner wywołuje tę funkcję na końcu pliku, więc możesz wskazać inny plik i kontynuować skanowanie jego zawartości. Jeśli tego nie potrzebujesz, użyj

%option noyywrap

w specyfikacji skanera.

Chociaż wyłączenie yywrap jest z pewnością najlepszą opcją, może być również możliwe połączenie z, -lflaby użyć domyślnej yywrap()funkcji w bibliotece fl(tj. libfl.a) Dostarczonej przez fleksa. Posix wymaga, aby ta biblioteka była dostępna z flagą konsolidatora, -lla domyślna instalacja systemu OS X zawiera tylko tę nazwę.

hjhill
źródło
1
Gdzie dokładnie należy dodać „% option noyywrap”? W sekcji definicji czy w wierszu poleceń?
yamex5
Dodałem go na początek .lpliku i lexzaakceptowałem! Nie jestem pewien, czy to najlepsze miejsce. Może to nie ma znaczenia.
Deepak
9

Wolę zdefiniować własny yywrap (). Kompiluję w C ++, ale sprawa powinna być oczywista. Jeśli ktoś wywoła kompilator z wieloma plikami źródłowymi, przechowuję je na liście lub w tablicy, a następnie na końcu każdego pliku wywoływana jest yywrap (), aby dać ci szansę na kontynuację z nowym plikiem.

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;
}
codenheim
źródło
3

flex nie zawsze instaluje się wraz ze swoimi bibliotekami programistycznymi (co jest dziwne, ponieważ jest to narzędzie programistyczne). Zainstaluj biblioteki, a życie będzie lepsze.

W systemach bazowych Redhat:

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

W systemach opartych na Debianie

sudo apt-get install libfl-dev
Des Cent
źródło
2

Uwaga dla obserwujących, flex 2.6.3 ma błąd, w którym libfl.a "zazwyczaj definiowałoby" yywrap, ale w niektórych przypadkach nie, więc sprawdź, czy to twoja wersja fleksa, może być związana z twoim problemem:

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

rogerdpack
źródło
1
int yywrap(){return(1);}

użyj tego kodu na końcu programu… Prosty

veeppiaar
źródło