Przyjęta odpowiedź jest niepoprawna. Spowoduje to wycieki pamięci.
Wewnętrznie, yy_scan_string wywołuje yy_scan_bytes, które z kolei wywołuje yy_scan_buffer.
yy_scan_bytes przydziela pamięć dla KOPIOWANIA bufora wejściowego.
yy_scan_buffer działa bezpośrednio na dostarczonym buforze.
We wszystkich trzech formularzach MUSISZ wywołać yy_delete_buffer, aby zwolnić informacje o stanie elastycznego bufora (YY_BUFFER_STATE).
Jednak przy pomocy yy_scan_buffer unika się wewnętrznego przydziału/kopiowania/usuwania wewnętrznego bufora.
Prototyp dla yy_scan_buffer NIE przyjmuje oznaczenia const * i NIE NALEŻY oczekiwać, że zawartość pozostanie niezmieniona.
Jeśli przeznaczyłeś pamięć na ciąg znaków, jesteś odpowiedzialny za jej zwolnienie PO POWINIENU zadzwonić yy_delete_buffer.
Pamiętaj również, aby mieć yywrap powrót 1 (niezerowy) podczas analizowania JUST ten ciąg.
Poniżej znajduje się przykład CAŁKOWICIE.
%%
<<EOF>> return 0;
. return 1;
%%
int yywrap()
{
return (1);
}
int main(int argc, const char* const argv[])
{
FILE* fileHandle = fopen(argv[1], "rb");
if (fileHandle == NULL) {
perror("fopen");
return (EXIT_FAILURE);
}
fseek(fileHandle, 0, SEEK_END);
long fileSize = ftell(fileHandle);
fseek(fileHandle, 0, SEEK_SET);
// When using yy_scan_bytes, do not add 2 here ...
char *string = malloc(fileSize + 2);
fread(string, fileSize, sizeof(char), fileHandle);
fclose(fileHandle);
// Add the two NUL terminators, required by flex.
// Omit this for yy_scan_bytes(), which allocates, copies and
// apends these for us.
string[fileSize] = '\0';
string[fileSize + 1] = '\0';
// Our input file may contain NULs ('\0') so we MUST use
// yy_scan_buffer() or yy_scan_bytes(). For a normal C (NUL-
// terminated) string, we are better off using yy_scan_string() and
// letting flex manage making a copy of it so the original may be a
// const char (i.e., literal) string.
YY_BUFFER_STATE buffer = yy_scan_buffer(string, fileSize + 2);
// This is a flex source file, for yacc/bison call yyparse()
// here instead ...
int token;
do {
token = yylex(); // MAY modify the contents of the 'string'.
} while (token != 0);
// After flex is done, tell it to release the memory it allocated.
yy_delete_buffer(buffer);
// And now we can release our (now dirty) buffer.
free(string);
return (EXIT_SUCCESS);
}
Hej dfa (który jest odpowiedni biorąc pod uwagę jego flex) czy mógłbyś dodać coś o wymogu podwójnej wartości zerowej ? –
Najprawdopodobniej główna próba zakończy się niepowodzeniem, ponieważ 'yy_scan_buffer' wymaga zapisywalnego bufora (tymczasowo modyfikuje bufor, wstawia NUL-y, aby zakończyć' yytext', a następnie przywraca oryginalne znaki), I wymaga DWÓCH kończących bajtów NUL. –
Przy okazji, w moim programie C++, musiałem zadeklarować 'yy_scan_bytes' z parametrem' size_t len', aby uniknąć błędów linkera. – coldfix