Ответ 1
Простым ответом является "Да".
В реферате вам вообще не нужны лексеры. Вы могли бы просто написать грамматик, который использовал отдельные символы в качестве токенов (и на самом деле именно то, что делают синтаксические анализаторы SGLR, но это история за другой день).
Вам нужны лексеры, потому что парсеры, созданные с использованием символов в качестве примитивных элементов, не так эффективны, как парсеры, которые разбивают входной поток на "токены", где токены - это примитивные элементы языка, который вы разыгрываете (пробелы, ключевые слова, идентификаторы, числа, операторы, строки, комментарии,...). [Если вы не заботитесь об эффективности, вы можете пропустить оставшуюся часть этого ответа и почитать о синтаксисе SGLR].
Хорошие лексеры обычно принимают наборы регулярных выражений, представляющих языковые элементы, и компилируют их в эффективный конечный конечный автомат, который может быстро сегментировать входной поток на такие языковые элементы. (Если вы не хотите, чтобы пользователь использовал генератор лексеров, для простых языков вы можете самостоятельно закодировать FSA). Такие скомпилированные FSA выполняют только несколько десятков машинных инструкций для каждого входного символа (получить символ из входного буфера, переключить символ в новое состояние, решить, завершен ли токен, если он не повторится), и поэтому может быть чрезвычайно быстрым.
Вывод таких лексеров обычно представляет собой код, представляющий элемент langauge (или ничего для пробелов, если парсер в любом случае игнорирует его) и некоторую информацию о местоположении (начинается в файле foo, строка 17, столбец 3), чтобы включить отчет об ошибках.
Можно остановиться там и иметь полезные лексеры. Часто бывает полезно сделать шаг преобразования, который преобразует строку символов в эквивалентное значение собственного компьютера для этого токена, либо по мере того, как символы собираются, либо когда токен завершен, потому что у него все еще есть знания о конкретных символах, участвующих в токен. Это используется для преобразования чисел (различных радиксов) на целевом языке в их родной двоичный эквивалент, для преобразования литеральных строк, содержащих escape-последовательности, в фактические символы, составляющие строку, и даже с именами идентификаторов и поиска их в хеш-таблице так что идентичные идентификаторы легко определяются. Парсер обычно не интересуется этими преобразованными значениями, но шаги, выходящие за рамки синтаксического анализа (семантический анализ, проверка для оптимизации, генерация кода), все равно нуждаются в преобразованных значениях, поэтому вы можете также преобразовать их, когда вы их обнаружите. (Вы можете отложить это преобразование до тех пор, пока не потребуется их двоичное значение, но на практике вам почти всегда нужно значение, поэтому отсрочка конвертации не очень сильно покупается).