Причины использования альтернатив lex/yacc?

Примерно раз в год мне приходится разрабатывать или, по крайней мере, составлять грамматику и синтаксический анализатор, который является постоянной моей рабочей жизнью.

Каждый раз, когда я сталкиваюсь с этой задачей, примерно один раз в год, я, довольно lex/yacc (flex/bison resp.) парень, рассматриваю или пересматриваю альтернативы для простого lex/yacc, а после некоторых размышлений и пытаюсь вернуться к простому lex/yacc.

Поскольку у меня есть CORBA-сервер в хабе приложения, я могу позвонить из парсера, написанного почти на каждом языке, поэтому на этот раз я посмотрел

  • antlr4 (Java) и antlr3 (Java, но имеет RT для других языков),
  • SableCC (Java),
  • Parse:: EBNF, Parse:: Yapp and Marpa (Perl),
  • и SimpleParse (Python),

Для меня тандем antlr4 с antlrworks выглядел самым перспективным кандидатом, но я еще не убежден, что время, потраченное на то, чтобы попасть в него, будет амортизировано в конце.


Грамматика, которую я должен разработать, похожа на SQL DDL (с точки зрения структуры, а не с точки зрения субъекта).

Почему любой из альтернатив облегчит мою задачу, чем использование простого lex/yacc?

Ответ 1

То, что вы также должны учитывать, это то, что разные генераторы парсеров генерируют совершенно разные парсеры. Yacc/bison генерируют синтаксические анализаторы снизу вверх, которые часто трудно понять, трудно отлаживать и давать странные сообщения об ошибках. ANTLR, например, создает рекурсивный нисходящий синтаксический анализатор, который значительно легче понять, вы можете легко отлаживать его (если у вас нет lemer 35MB, как я,), вы можете использовать только субрулы для (например, просто разбор выражений вместо полного языка).

Кроме того, его исправление ошибок намного лучше и дает намного более чистые ошибки. Там ANTLRWorks - отличное кросс-платформенное приложение для разработки и отладки вашей грамматики (отладка, только если вы используете цель Java). Цели Apropros: вы можете генерировать парсеры на разных языках (C, С++, С#, Java и другие) из той же грамматики, если у вас нет специфических для языка действий в вашей грамматике (вы уже упомянули об этом в своем вопросе). И хотя мы говорим о действиях: из-за принципа оценки в нижнем парсере (маркер сдвига, токен сдвига, сводить их к новому токену и сдвигать его и т.д.), Действия могут легко вызвать проблемы там, например. выполняются не один раз, а такие. Не так с парсерами, генерируемыми ANTLR.

Я также пробовал различные генераторы парсеров на протяжении многих лет, даже писал свои собственные, но я бы в любое время рекомендовал ANTLR как инструмент выбора.

Ответ 2

последний Marpa - Marpa:: R2, который имеет большие улучшения в "whipituptude", включая очень удобный новый DSL-интерфейс, который сам написан в Marpa. Вы можете подумать о том, чтобы начать с Марпы, для "прототипирования". Марпа очень декларативный, используя чистый BNF. Если вы уйдете, вы можете перенести большую часть своей работы на новый парсер. Marpa является непревзойденной в обработке и обнаружении ошибок, также очень удобной в фазе прототипирования.

Марпа анализирует все классы грамматики, анализируемые другими парсерами, перечисленными в линейном времени, и непревзойден в своей гибкости. Его новейшая функция позволяет вам переключаться между Marpa и вашим собственным парсинговым кодом. Так что вы даже можете остаться с ним. Существует веб-сайт, а в моем блоге серия учебников, что может быть лучшим способом познакомиться с Марпой.