Разбор YAML - лекс или раскатанный вручную? - PullRequest
6 голосов
/ 19 сентября 2011

Я пытаюсь написать простой парсер YAML, я прочитал спецификацию с yaml.org, перед тем, как начать, мне было интересно, лучше ли написать обработчик, созданный вручную, или используйте lex (flex/bison). Я посмотрел на libyaml (библиотека C) - похоже, не использует lex/yacc. YAML (исключая стили потока ), кажется более ориентированным на строки, так что проще написать свернутый вручную парсер или использовать flex/bison Спасибо.

1 Ответ

3 голосов
/ 17 июня 2014

Этот ответ в основном является ответом на вопрос: «Должен ли я свернуть свой собственный анализатор или использовать генератор анализатора?» и не имеет ничего общего с YAML. Но тем не менее он «ответит» на ваш вопрос.

Вопрос, который вам нужно задать, заключается не в том, «работает ли это с данным языком / грамматикой», а в том, «чувствую ли я себя уверенно, чтобы реализовать это». Дело в том, что большинство форматов, которые вы хотите проанализировать, будут работать только с сгенерированным парсером. Другая правда состоит в том, что возможно анализировать даже сложные языки простым написанным от руки парсером рекурсивного спуска .

Я написал, среди прочего, парсер рекурсивного спуска для EDDL (C и структурированные элементы) и парсер бизонов / флекс для INI. Я выбрал эти примеры, потому что они идут вразрез с интуицией, и внешние требования диктовали решение.

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

  • Написание хорошего лексера действительно сложно. В большинстве случаев имеет смысл использовать flex для создания лексера. Тебе не нужно скручивать вручную свой собственный лексер, если только у тебя нет действительно экзотических форматов ввода.
  • Использование зубров или аналогичных генераторов делает грамматику, используемую для синтаксического анализа, явно видимой. Основным преимуществом здесь является то, что разработчик, обслуживающий ваш парсер через пять лет, сразу увидит используемую грамматику и сможет сравнить ее с любыми спецификациями.
  • Использование парсера с рекурсивным спуском делает вполне понятным, что происходит в парсере. Это обеспечивает легкий способ изящно справиться с гарри-конфликтами. Вы можете написать простое, если вместо перестановки всей грамматики в LALR1.
  • При разработке синтаксического анализатора вы можете «затушевывать детали» с помощью рукописного синтаксического анализатора, используя бизона это практически невозможно. В бизоне должна работать грамматика, иначе генератор ничего не сделает.
  • Бизон замечательно указывает на формальные недостатки в грамматике. К сожалению, вы остались одни, чтобы исправить их. При ручном раскатывании парсера вы найдете недостатки только тогда, когда парсер читает глупости.

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

...