Это работа лексера для разбора чисел и строк? - PullRequest
31 голосов
/ 12 июня 2011

Является ли лексером работа по анализу чисел и строк?

Это может звучать или не звучать глупо, учитывая тот факт, что я спрашиваю, должен ли lexer анализировать ввод.Тем не менее, я не уверен, является ли это на самом деле работой лексера или работой парсера, потому что для того, чтобы правильно выполнить лекс, лексеру нужно сначала проанализировать строку / число , поэтомукак если бы синтаксический анализатор это делал, то он дублировался бы.

Действительно ли это работа лексера?Или же лексеру нужно просто разбить строку типа 123.456 на строки 123, ., 456 и позволить анализатору выяснить все остальное?Делать это было бы не так просто со строками ...

Ответы [ 3 ]

31 голосов
/ 12 июня 2011

Простой ответ - «Да».

В реферате вам вообще не нужны лексеры. Вы могли бы просто написать грамматику, которая использовала бы отдельные символы в качестве токенов (и фактически это именно то, что делают парсеры SGLR, но это история для другого дня).

Вам нужны лексеры, потому что парсеры, созданные с использованием символов в качестве примитивных элементов, не так эффективны, как парсеры, которые разбивают входной поток на «токены», где токены - это примитивные элементы языка, который вы анализируете (пробелы, ключевые слова, идентификаторы, числа, операторы, строки, комментарии, ...). [Если вам не нужна эффективность, вы можете пропустить оставшуюся часть этого ответа и прочитать о парсерах SGLR].

Хорошие лексеры обычно принимают наборы регулярных выражений, представляющих элементы языка, и компилируют их в эффективный конечный автомат, который может быстро сегментировать входной поток в такие элементы языка. (Если вы не хотите использовать генератор лексеров, для простых языков вы можете написать код FSA самостоятельно). Такие скомпилированные FSA выполняют только несколько десятков машинных инструкций для каждого входного символа (получают символ из входного буфера, переключают символ в новое состояние, решают, завершен ли токен, если не делают это снова), и, таким образом, могут быть чрезвычайно быстрыми.

Вывод таких лексеров обычно представляет собой код, представляющий элемент языка (или ничего для пробела, если анализатор все равно его игнорирует), и некоторую информацию о положении (начинается в файле foo, строка 17, столбец 3) для включения отчетов об ошибках.

На этом можно остановиться и получить полезные лексеры. Часто бывает полезно сделать шаг преобразования, при котором строка символов преобразуется в эквивалентное значение собственного компьютера для этого токена, либо когда символы собраны, либо когда токен завершен, потому что каждый еще знает о конкретных символах, участвующих в знак Это используется для преобразования чисел (различающихся оснований) на целевом языке в их собственный двоичный эквивалент, для преобразования буквенных строк, содержащих escape-последовательности, в фактические символы, составляющие строку, и даже взятия имен идентификаторов и поиска их в хеш-таблице так что идентичные идентификаторы легко определяются. Синтаксический анализатор обычно не интересуется этими конвертированными значениями, но для шагов, выходящих за рамки синтаксического анализа (семантический анализ, проверка на оптимизацию, генерация кода), все равно нужны конвертированные значения, так что вы можете преобразовать их по мере их обнаружения. (Вы можете отложить это преобразование до тех пор, пока не понадобится их двоичное значение, но на практике вам почти всегда нужно это значение, поэтому задержка преобразования не очень выгодна).

0 голосов
/ 12 июня 2011

Лексер по сути идентифицирует токены из входных данных.В этом случае лексер, возможно, «совпадет» с числом как число с плавающей запятой TOKEN.Парсер по сути обрабатывает токены и выполняет синтаксический анализ

0 голосов
/ 12 июня 2011

Я предполагаю, что вы хотите обработать "123.456" как целое значение, и в этом случае вы передадите его оптом парсеру, если вам не нужно каким-либо образом его кодировать, например

struct DecimalRep{
    double mantissa,
    double exponent 

}

но я думаю, все зависит от того, что ожидает парсер.

...