Оскільки ви хочете дізнатися, як працюють лексери, я припускаю, що ви насправді хочете знати, як працюють генератори лексерів.
Генератор лексерів приймає лексичну специфікацію, яка є переліком правил (пари регулярних виразів-лексем) і генерує лексеру. Потім отриманий лексер може перетворити вхідний (символьний) рядок у рядок лексеми відповідно до цього списку правил.
Метод, який найчастіше використовується в основному, полягає в перетворенні регулярного виразу в детерміновані кінцеві автомати (DFA) через недетерміновані автомати (NFA), а також кілька деталей.
Детальний посібник щодо здійснення цієї трансформації можна знайти тут . Зауважте, що я сам цього не читав, але це виглядає досить непогано. Крім того, майже в будь-якій книзі про побудову компілятора буде показано це перетворення в перших кількох главах.
Якщо вас цікавлять слайди лекцій курсів з даної теми, без сумніву, нескінченна кількість їх із курсів з побудови компілятора. З мого університету ви можете знайти такі слайди тут і тут .
Є ще кілька речей, які зазвичай не використовуються в лексемах або не обробляються текстами, але все-таки є досить корисними:
По-перше, поводження з Unicode дещо нетривіально. Проблема полягає в тому, що вхід ASCII має ширину лише 8 біт, а це означає, що ви можете легко мати таблицю переходу для кожного стану в DFA, оскільки у них є лише 256 записів. Однак для Unicode шириною 16 біт (якщо ви використовуєте UTF-16) потрібно 64 кб таблиці для кожного запису в DFA. Якщо у вас складні граматики, це може почати займати досить багато місця. Заповнення цих таблиць також починає забирати зовсім небагато часу.
Крім того, ви можете генерувати інтервальні дерева. Дерево діапазону може містити, наприклад, кортежі ('a', 'z'), ('A', 'Z'), що набагато ефективніше пам'яті, ніж повна таблиця. Якщо ви підтримуєте інтервали, що не перетинаються, для цього можна використовувати будь-яке збалансоване двійкове дерево. Час виконання лінійно в кількості бітів, необхідних для кожного символу, тому O (16) у випадку Unicode. Однак у кращому випадку, як правило, це буде зовсім трохи менше.
Ще одне питання полягає в тому, що лексери, як зазвичай генеруються, насправді мають найгірший квадратичний показник. Хоча таке гірше поведінка не часто зустрічається, воно може вас вкусити. Якщо ви зіткнулися з проблемою і хочете її вирішити, тут можна знайти документ, що описує, як досягти лінійного часу .
Ймовірно, ви хочете мати можливість описувати регулярні вирази в рядковій формі, як вони зазвичай з’являються. Однак аналіз цих описів регулярних виразів на NFA (або, можливо, спочатку рекурсивну проміжну структуру) є дещо проблемою з курячим яйцем. Для розбору описів регулярних виразів дуже підходить алгоритм Shunting Yard. У Вікіпедії, здається, є велика сторінка алгоритму .