Ponieważ chcesz dowiedzieć się, jak działają leksykony, zakładam, że tak naprawdę chcesz wiedzieć, jak działają generatory leksykalne.
Generator leksykalny pobiera specyfikację leksykalną, która jest listą reguł (pary wyrażenia regularnego-token), i generuje leksyk. Ten wynikowy leksyk może następnie przekształcić łańcuch wejściowy (znakowy) w łańcuch tokena zgodnie z tą listą reguł.
Najczęściej stosowana metoda polega głównie na przekształceniu wyrażenia regularnego w deterministyczne automaty skończone (DFA) za pomocą niedeterministycznych automatów (NFA) oraz kilku szczegółów.
Szczegółowy przewodnik wykonywania tej transformacji można znaleźć tutaj . Pamiętaj, że sam tego nie przeczytałem, ale wygląda całkiem dobrze. Ponadto, prawie każda książka o budowie kompilatora będzie zawierała tę transformację w kilku pierwszych rozdziałach.
Jeśli interesują Cię wykłady z wykładów na ten temat, bez wątpienia jest ich nieskończona ilość z kursów na temat budowy kompilatora. Z mojej uczelni możesz znaleźć takie slajdy tutaj i tutaj .
Jest jeszcze kilka rzeczy, które nie są powszechnie używane w leksykach lub traktowane w tekstach, ale mimo to są całkiem przydatne:
Po pierwsze, obsługa Unicode nie jest łatwa. Problem polega na tym, że wejście ASCII ma tylko 8 bitów szerokości, co oznacza, że możesz łatwo mieć tabelę przejścia dla każdego stanu w DFA, ponieważ mają one tylko 256 wpisów. Jednak Unicode, mający szerokość 16 bitów (jeśli używasz UTF-16), wymaga 64k tabel dla każdego wpisu w DFA. Jeśli masz złożoną gramatykę, może to zająć sporo miejsca. Wypełnianie tych tabel również zajmuje sporo czasu.
Alternatywnie możesz wygenerować drzewa interwałów. Drzewo zakresu może zawierać na przykład krotki („a”, „z”), („A”, „Z”), co jest o wiele bardziej wydajne pod względem pamięci niż posiadanie pełnej tabeli. Jeśli zachowasz nie nakładające się interwały, możesz w tym celu użyć dowolnego zbalansowanego drzewa binarnego. Czas działania jest liniowy w liczbie bitów potrzebnej dla każdego znaku, więc O (16) w przypadku Unicode. Jednak w najlepszym przypadku zwykle będzie to nieco mniej.
Kolejną kwestią jest to, że tak często generowane leksykony mają w najgorszym przypadku kwadratową wydajność. Chociaż to najgorsze zachowanie nie jest często spotykane, może cię ugryźć. Jeśli napotkasz problem i chcesz go rozwiązać, możesz znaleźć tutaj artykuł opisujący, jak osiągnąć czas liniowy .
Prawdopodobnie będziesz chciał móc opisywać wyrażenia regularne w postaci ciągów, tak jak zwykle się pojawiają. Jednak parsowanie tych opisów wyrażeń regularnych na NFA (lub prawdopodobnie najpierw rekurencyjną strukturę pośrednią) jest trochę problemem z jajkiem kurzym. Do analizowania opisów wyrażeń regularnych bardzo odpowiedni jest algorytm Shunting Yard. Wydaje się, że Wikipedia ma obszerną stronę dotyczącą algorytmu .