top of page

Parser plików tekstowych – text-syntax.cx

Zaktualizowano: 15 lip 2022

W module “base” jest dostępny parser plików tekstowych kodowanych w UTF-8.

Do przetworzenia takiego pliku tekstowego są potrzebne dwa pliki:

  • plik opisu składni (zazwyczaj z rozszerzeniem “.syntax”) w formacie UTF-8

  • plik parsowany z tekstem UTF-8


Wczytywanie opisu składni pliku tekstowego

Najpierw należy utworzyć obiekt pliku opisu składni w menedżerze plików, a następnie utworzyć obiekt składni w module parsera plików procedurą:

N
E_text_syntax_M( I file
, struct E_text_syntax_Z_body **syntax
);

przed wywołaniem której “syntax” należy zadeklarować jako:

struct E_text_syntax_Z_body *syntax;

i podać w wywołaniu procedury wskaźnik do tej zmiennej jak poniżej:

if( !~E_text_syntax_M( file, &syntax ))
    // ...

Parsowanie pliku tekstowego

Wtedy trzeba odczytać i przypisać zmiennym identyfikatory poszczególnych nazw ‘entities’ z pliku opisu składni procedurą:

N
E_text_syntax_R_entity_by_name( struct E_text_syntax_Z_body *syntax
, Pc name
);

które zostaną wykorzystane podczas jego parsowania.

Następnie utworzyć obiekt stanu parsowania, utworzyć obiekt parsowanego pliku tekstowego w menedżerze plików i uruchomić parsowanie pliku tekstowego procedurami:

N
E_text_syntax_Q_state_M( struct E_text_syntax_Z_body *syntax
, struct E_text_syntax_Z_state **state
, N *state_n
);
N
E_text_syntax_Q_state_I_parse( I file
, struct E_text_syntax_Z_body *syntax
, struct E_text_syntax_Z_state **state
, N *state_n
, N (*entities_func)( struct E_text_syntax_Z_body *, struct E_text_syntax_Z_state *, N )
);

A na zakończenie wyrzucić obiekt stanu parsowania procedurą:

void
E_text_syntax_Q_state_W( struct E_text_syntax_Z_state *state
, N state_n
);

Na przykład:

N entities_path = E_text_syntax_R_entity_by_name( syntax, "path" );
N entities_port = E_text_syntax_R_entity_by_name( syntax, "port" );
if( !~entities_path
|| !~entities_port
)
    // ...
struct E_text_syntax_Z_body *syntax;
struct E_text_syntax_Z_state *state;
N state_n;
if( !~E_text_syntax_Q_state_M( syntax, &state, &state_n ))
    // ...
if( !~E_text_syntax_Q_state_I_parse( parsed_file, syntax, &state, &state_n, &entities_func ))
    // ...
E_text_syntax_Q_state_W( state, state_n );

Do parsowania pliku tekstowego potrzeba zdefiniować procedurę parsowania wszystkich nazw ’entities’ z pliku opisu składni, podaną powyżej do procedury parsowania jako “entities_func”.


Procedura parsowania wszystkich nazw ‘entities’

Dla każdego ‘entity’ z pliku opisu składni dopasowanego w parsowanym od początku do końca pliku tekstowym zostanie wywołana podana procedura “entities_func”:

N
entities_func( struct E_text_syntax_Z_body *syntax
, struct E_text_syntax_Z_state *state
, N state_n
);

w której w każdym jej wywołaniu na wierzchołku stosu “state” (czyli w “state[ state_n - 1 ]”) będzie identyfikator i tekst bieżąco dopasowanego ‘entity’. W tej procedurze należy odczytać sobie tekst dopasowania dla rozpoznawanego ‘entity’ i ustawić odpowiedni stan parsowania. Jeśli procedura ta wraca z 0, to parsowanie jest kontynuowane, w przeciwnym przypadku – przerywane.

Polami struktury służącymi do odczytu tych danych są:

struct E_text_syntax_Z_state
{ // ...
  N entities_i; // identyfikator ‘entity’
  Pc s; // tekst dopasowania
  // ...
};

Format pliku opisu składni

Plik zawiera kilkuliniowe ‘entities’ dopasowywane do kolejno czytanych od początku do końca elementów pliku tekstowego.

Przykładowe pliki opisu składni są tutaj:

Pierwsze z ‘entities’ jest tym, które zawiera strukturę całego dokumentu.

‘Entities’ mają format:

nazwa entity:
/ nazwa entity odstępów pomiędzy poniższymi
    nazwa zawartego entity
    dopasowanie wbudowane

Przy czym kolejność linii i ich liczba jest dowolna, a nazwa ‘entity’ odstępów jest opcjonalne.

Nazwa ‘entity’ jest nazwą Unicode, z dozwolonymi odstępami wewnątrz. Ta nazwa użyta w innym ‘entity’ musi być takim samym ciągiem tekstowym.

Dopasowanie wbudowane to jest jedno z:

  • tekst

  • zanegowany tekst

  • wyrażenie regularne (zgodne z opisanym w “man 7 regex”)

  • zanegowane wyrażenie regularne (zbiera tekst do momentu dopasowania wyrażenia regularnego)

  • wyrażenie wbudowane

Tekst jest otaczany znakami podwójnego cudzysłowu, zanegowany tekst dodatkowo poprzedzany znakiem wykrzyknika, wyrażenie regularne otaczane znakami ukośnika, zanegowane wyrażenie regularne dodatkowo poprzedzane znakiem wykrzyknika, wyrażenie wbudowane jest poprzedzane znakiem “@”. Na przykład:

dopasowanie wbudowane:
    "tekst" | !"tekst" | /wyrażenie regularne/ | !/zanegowane wyrażenie regularne/ | @alpha | @digit | @text | @eof

Nazwa ‘entity’ zawartego w ‘entity’ może być zakończona znakiem “?”, wtedy ‘entity’ to jest opcjonalne, albo znakami “...”, wtedy ‘entity’ to może się powtarzać. Oba te ciągi końcowe muszą być poprzedzone pojedynczym odstępem.

W miejscu ‘entity’ zawartego w ‘entity’ może być kilka nazw ‘entities’ rozdzielonych przecinkami lub znakiem pionowej kreski “|”. W pierwszym przypadku mają znaczenie takie jakby były w kolejnych liniach, w drugim przypadku są wobec siebie alternatywnymi dopasowaniami.

60 wyświetleń0 komentarzy

Ostatnie posty

Zobacz wszystkie

Klient HTTP/1.1 i HTTP/2

Do modułu “base” dodałem podstawową obsługę klienta HTTP/1.1 i HTTP/2, korzystając z szyfrowania TLS zapewnianego przez OpenSSL. Procedura inicjująca połączenie automatycznie negocjuje najwyższy możli

Duże liczby jakby zmiennoprzecinkowe – math-bignum.cx

Moduł dużych liczb pozwala przechowywać w postaci dwójkowej liczby większe niż liczba naturalna procesora i przeprowadzać na nich obliczenia. Są to liczby bardzo podobne do liczb zmiennoprzecinkowych.

Menedżer plików – mem-file.cx

Menedżer plików obsługuje zarówno losowe jak i strumieniowe czytanie i zapisywanie do pliku. Przechowuje on w pamięci podręcznej dotychczas odczytaną zawartość pliku i w regularnych odstępach czasowyc

bottom of page