Когда я начал использовать комбинаторы синтаксического анализа, моей первой реакцией было чувство освобождения от того, что казалось искусственным различием между синтаксическим анализом и лексингом. Внезапно все было просто разбор!
Однако недавно я наткнулся на эту публикацию на codereview.stackexchange, иллюстрирующую кого-то, кто вновь подтверждает это различие. Сначала я думал, что это было очень глупо с их стороны, но затем тот факт, что в Parsec существуют функции для поддержки такого поведения, заставляет меня задаться вопросом.
Каковы преимущества / недостатки синтаксического анализа уже лексированного потока в комбинаторах синтаксического анализа?
parsing
lexer
parser-combinator
Эли Фрей
источник
источник
Ответы:
Под синтаксическим анализом мы чаще всего понимаем анализ контекстно-свободных языков. Свободный от контекста язык более мощный, чем обычный, поэтому синтаксический анализатор может (чаще всего) выполнять работу лексического анализатора сразу.
Но это а) довольно неестественно б) часто неэффективно.
Для a), если я думаю о том, как, например,
if
выглядит выражение, я думаю, ЕСЛИ expr THEN expr ELSE expr, а не 'i' 'f', возможно, некоторые пробелы, тогда любой символ, с которого может начинаться выражение, и т. Д. идея.Для б) существуют мощные инструменты, которые отлично справляются с распознаванием лексических сущностей, таких как идентификаторы, литералы, скобки всех видов и т. Д. Они выполнят свою работу практически в кратчайшие сроки и предоставят вам удобный интерфейс: список токенов. Больше не нужно пропускать пробелы в парсере, ваш парсер будет гораздо более абстрактным, когда он имеет дело с токенами, а не с символами.
В конце концов, если вы считаете, что парсер должен быть занят вещами низкого уровня, зачем вообще обрабатывать символы? Можно написать и на уровне битов! Видите ли, такой синтаксический анализатор, который работает на уровне битов, будет почти непостижимым. То же самое и с персонажами и жетонами.
Просто мои 2 цента.
источник
if = string "if" >> expr >> string "then" >> expr >> string "else" >> expr
.Все, кто полагает, что разделение лексических операций и синтаксического анализа - это «хорошая практика» - я должен не согласиться - во многих случаях выполнение лексических операций и синтаксического анализа за один проход дает гораздо больше возможностей, и последствия для производительности не так плохи, как они представлены в другие ответы (см. Пакрат ).
Этот подход проявляется, когда нужно смешать несколько разных языков в одном потоке ввода. Это необходимо не только для странных, ориентированных на метапрограммирование языков, таких как Katahdin и тому подобное , но и для гораздо большего числа основных приложений, таких как грамотное программирование (смешивание латекса и, скажем, C ++), использование HTML в комментариях, вставка Javascript в HTML и скоро.
источник
Лексический анализатор распознает обычный язык, а синтаксический анализатор распознает язык без контекста. Поскольку каждый обычный язык также не зависит от контекста (его можно определить с помощью так называемой линейно - правильной грамматики ), синтаксический анализатор также может распознавать обычный язык, и различие между синтаксическим анализатором и лексическим анализатором добавляет некоторую ненужную сложность: один контекст Свободная грамматика (парсер) может выполнять работу парсера и лексического анализатора.
С другой стороны, может быть полезно захватить некоторые элементы языка без контекста через обычный язык (и, следовательно, лексический анализатор), потому что
Таким образом, отделение синтаксического анализа от лексического анализа имеет то преимущество, что вы можете работать с более простой неконтекстной грамматикой и инкапсулировать некоторые базовые (часто рутинные) задачи в лексическом анализаторе (split et impera).
РЕДАКТИРОВАТЬ
Я не знаком с комбинаторами синтаксического анализа, поэтому я не уверен, как вышеуказанные соображения применимы в этом контексте. У меня сложилось впечатление, что даже если с комбинаторами синтаксического анализа есть только одна не зависящая от контекста грамматика, различие между двумя уровнями (лексический анализ / анализ) может помочь сделать эту грамматику более модульной. Как уже говорилось, нижний уровень лексического анализа может содержать базовые парсеры многократного использования для идентификаторов, литералов и так далее.
источник
\alpha'_1 (K_0, \vec{T})
, где \ alpha'_1, K_0 и \ vec {T} являются идентификаторами.Проще говоря, лексизм и синтаксический анализ должны быть разделены, потому что это разные сложности. Лексинг - это DFA (детерминированный конечный автомат), а синтаксический анализатор - это PDA (автомат с нажатием). Это означает, что синтаксический анализ по своей сути потребляет больше ресурсов, чем лексирование, и существуют специальные методы оптимизации, доступные только для DFA. Кроме того, написание конечного автомата гораздо менее сложно, и его легче автоматизировать.
Вы расточительны, используя алгоритм синтаксического анализа для lex.
источник
Одним из основных преимуществ отдельных parse / lex является промежуточное представление - поток токенов. Это может быть обработано различными способами, которые иначе были бы невозможны при комбинированном lex / parse.
Тем не менее, я обнаружил, что хорошее рекурсивное приличие может быть менее сложным и легче работать с обучением некоторому генератору синтаксического анализатора и необходимости выяснить, как выразить слабость грамматики в правилах генератора синтаксического анализатора.
источник