Основная причина этого заключается в том, что большинство синтаксических анализаторов LL (k), написанных на функциональных языках, просто реализуются с использованием комбинаторов синтаксического анализа, поскольку самый простой путь для создания библиотеки комбинатора синтаксического анализатора - рекурсивное спуск .
* Haskell парсек , attoparsec и polyparse и комбинаторы парсера стокового кода Scala - все, что фактически является парсерами LL (*).
И parsec, и attoparsec требуют, чтобы вы использовали явный комбинатор try для возврата назад, но это делается только для повышения эффективности, и комбинаторы синтаксического анализа scala также могут работать с синтаксическим анализом пакетов.1016 *.
Рассмотрим следующий фрагмент из анонса недавнего несвязанного пакета Брента Йорги:
parseAtom = parens parseTerm
<|> var <$> ident
<|> lam <$> brackets ident <*> parseTerm
это довольно легко увидетьисходная грамматика.
LR-синтаксические анализаторы требуют гораздо более сложной предварительной обработки для генерации таблиц для эффективного выполнения, поскольку прямое ручное кодирование одного с использованием чего-то вроде рекурсивного подъема довольно ужасно.
Реализуя свои комбинаторы синтаксического анализа как EDSL, а не как внешний инструмент, вы расширяете возможности использования расширенных функций вашего языка программирования.Вы можете сделать части грамматики более высокого порядка, встроить лексер-хак непосредственно в синтаксический анализатор и т. Д. Типичные генераторы синтаксического анализатора LR не могут делать эти вещи или могут предлагать их только специальными способами в ограниченном контексте.из-за необходимости иметь возможность создавать таблицы в конце.