yacc/lex или ручное кодирование?

Я работаю над новым языком программирования, но я всегда был озадачен тем фактом, что все используют yaxx / lex для разбора кода, а я нет.

Мой компилятор (который уже работает) написан вручную на C++/STL, и я не могу сказать, что он сложный или занял слишком много времени. У него есть как лексер, так и парсер, но они не генерируются автоматически.

Ранее я написал компилятор C (не полную спецификацию) тем же способом - он смог скомпилировать программу за 1 проход, с разрешением и предварительной обработкой всех обратных ссылок - это определенно невозможно с помощью yacc/lex.

Я просто не могу убедить себя отказаться от всего этого и начать погружаться в yaxx / lex - что может потребовать значительных усилий для реализации и может ввести некоторые грамматические ограничения.

Есть что-то, что я пропускаю, когда не использую yacc/lex? Я делаю зло?

5 ответов

Решение

Yacc негибок в некоторых отношениях:

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

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

Я не использовал ANTLR, поэтому я не могу сказать, лучше ли это в этих точках.

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

Другое огромное преимущество использования генераторов состоит в том, что они гарантированно обрабатывают точно и только тот язык, который вы указали в грамматике. Вы не можете сказать это ни о каком рукописном коде. Варианты LR/LALR также гарантированно равны O(N), что опять-таки нельзя утверждать ни о каком ручном кодировании, по крайней мере, без особых усилий при создании доказательства.

Я написал оба и жил с обоими, и я никогда больше не буду писать код вручную. Я сделал это только потому, что в то время у меня не было yacc на платформе.

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

Потенциально есть некоторые преимущества использования Yacc/Lex, но их использование не обязательно. Есть и недостатки использования Yacc/Lex, но преимущества обычно перевешивают недостатки. В частности, часто легче поддерживать грамматику, основанную на Yacc, чем ручную, и вы получаете выгоду от автоматизации, которую обеспечивает Yacc.

Однако написание собственного парсера с нуля не является чем-то злым. Это может усложнить поддержание в будущем, но может и облегчить.

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

Взгляните, возможно, на худший из возможных примеров: C++:) (Кто-нибудь знает другой язык, кроме естественных языков, которые сложнее правильно анализировать?) Даже с такими инструментами, как Antlr, довольно сложно сделать это правильно, хотя это управляемо. При этом, с другой стороны, даже несмотря на то, что это намного сложнее, кажется, что некоторые из лучших синтаксических анализаторов C++, например, GCC и LLVM, также в основном написаны от руки.

Если вам не нужно слишком много гибкости и ваш язык не слишком тривиален, вы наверняка сэкономите некоторую работу / время, используя Antlr.

Другие вопросы по тегам