Parsec или счастливый (с alex) или uu-parsinglib

Я собираюсь написать парсер verilog (или vhdl) и сделать много манипуляций (вроде преобразований) проанализированных данных. Я намерен разбирать действительно большие файлы (полный дизайн Verilog, размером до 10K строк), и я в конечном итоге поддержу большую часть Verilog. Я не против ввода текста, но я не хочу переписывать какую-либо часть кода всякий раз, когда я добавляю поддержку некоторого другого правила.

В Haskell, какую библиотеку вы бы порекомендовали? Я знаю Haskell и использовал Happy before (чтобы играть). Я считаю, что есть возможности использования Parsec для преобразования анализируемой строки в код (что является большим плюсом). У меня нет опыта работы с uu-paringlib.

Итак, чтобы разобрать полную грамматику verilog/VHDL, какую из них рекомендуется? Моя главная забота - это легкость и "правильность", с которыми я могу манипулировать анализируемыми данными по моей прихоти. Скорость не является основной задачей.

Ответы

Ответ 1

Я лично предпочитаю Parsec с помощью Alex для lexing.

Я предпочитаю Parsec над Happy, потому что 1) Parsec - это библиотека, а Happy - это программа, и вы будете писать на другом языке, если будете использовать Happy, а затем скомпилируйте Happy. 2) Parsec дает вам контекстно-зависимые возможности синтаксического анализа благодаря своему монадическому интерфейсу. Вы можете использовать дополнительное состояние для контекстно-зависимого разбора, а затем проверить и решить в зависимости от этого состояния. Или просто взгляните на некоторые анализируемые значения до и решите следующие синтаксические анализаторы и т.д. (Например, a <- parseSomething; if test a then ... do ...). И когда вам не нужна контекстно-зависимая информация, вы можете просто использовать аппликативный стиль и получить реализацию, реализованную в YACC или аналогичный инструмент.

Как недостаток Parsec, вы никогда не узнаете, содержит ли ваш парсер парсера левую рекурсию, и ваш синтаксический анализатор застрянет во время выполнения (потому что Parsec в основном представляет собой парсер с рекурсивным спусканием сверху вниз). Вы должны найти левые рекурсии и устранить их. Парсеры в стиле YACC могут дать вам некоторые статические гарантии и информацию (например, конфликты сдвига/уменьшения, неиспользуемые терминалы и т.д.), Которые вы не можете получить с Parsec.

Алекс настоятельно рекомендуется для лексинга в обеих ситуациях (Я думаю, вам нужно использовать Alex, если вы решите продолжить Happy). Потому что, даже если вы используете Parsec, он действительно упрощает реализацию парсера и улавливает множество ошибок (например: синтаксический анализ ключевого слова как идентификатора был распространенной ошибкой, которую я делал, когда использовал Parsec без Alex.).

Вы можете посмотреть мой Lua parser, реализованный в Alex + Parsec. И здесь чтобы использовать токены, созданные Алексом, в Parsec.

EDIT: Спасибо John L за исправления. По-видимому, вы можете делать контекстно-зависимый синтаксический разбор с Happy. Кроме того, Алекс для лексинга не требуется в Happy, хотя он рекомендовал.