Узнать больше о разборе - PullRequest
9 голосов
/ 28 июня 2009

Я программирую с 1999 года для работы и развлечений. Я хочу изучать новые вещи, и в последнее время я сосредоточился на анализе, поскольку большая часть моей работы заключается в чтении, интеграции и анализе данных. У меня также есть большое количество повторяющихся задач, которые, я думаю, я мог бы выразить на очень простых предметно-ориентированных языках, если бы издержки были достаточно низкими. У меня есть несколько вопросов по этому вопросу.

  1. Большая часть моего текущего кода синтаксического анализа не определяет формальную грамматику. Я обычно хакую что-то вместе на своем языке по выбору, потому что это легко, я знаю, как это сделать, и я могу написать этот код очень быстро. Это также легко для других людей, с которыми я работаю, чтобы поддерживать. Каковы преимущества и недостатки определения грамматики и генерации реального синтаксического анализатора (как можно было бы сделать с ANTLR или YACC ) для разбора вещей по сравнению со взломами, которые большинство программистов использовали для написания парсеры?
  2. Каковы лучшие инструменты генерации парсеров для написания грамматических парсеров на C ++, Perl и Ruby? Я посмотрел на ANTLR и почти ничего не нашел об использовании ANTLRv3 с целью C ++, но в остальном это выглядит интересно. Какие еще инструменты, которые похожи на ANTLR, о которых мне следует прочитать?
  3. Какие канонические книги и статьи, которые кто-то заинтересовал, чтобы узнать больше о разборе? К сожалению, курс по компиляторам не был частью моего образования, поэтому базовый материал очень приветствуется. Я слышал замечательные вещи о Книге Дракона , но что еще там?

Ответы [ 8 ]

4 голосов
/ 28 июня 2009

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

На 2. и 3. я не могу предложить намного больше того, что вы уже нашли (я в основном использую Python и pyparsing, и могу прокомментировать из опыта многих Python-центрированных сред синтаксического анализа, но для C ++ я в основном использую в любом случае, старый добрый yacc или bison, и моя старая скрюченная копия Книги Дракона - на самом деле, не последнее издание - это все, что я держу для своей цели ...).

4 голосов
/ 28 июня 2009

Вот мои ответы на ваши (очень хорошие) вопросы:

  1. Я думаю, что синтаксический анализатор выигрывает больше всего от нетривиальных ситуаций, когда грамматика действительно существует. Вы должны знать, как работают парсеры и грамматики, чтобы думать об этой технике, и не каждый разработчик знает.
  2. lex / yacc - это старые Unix-инструменты, которые могут быть полезны вам как разработчику C ++. Может быть, и Бизон.
  3. ANTRL и его сопровождающая книга очень хороши. "Написание компиляторов и интерпретаторов" содержит примеры C ++, которые могут вам понравиться.

Шаблон GoF Interpreter - еще один метод написания «маленьких языков». Взгляните на это.

2 голосов
/ 30 июня 2009

Я бы серьезно взглянул на синтаксический анализ на основе монадических комбинаторов (который также часто связан с лексическим анализом) в Haskell. Я нашел это довольно откровением; Удивительно, как легко вы можете создать парсер с нуля, используя этот метод. На самом деле это настолько просто, что зачастую быстрее написать свой собственный анализатор, чем пытаться использовать существующие библиотеки.

Самым известным примером является, вероятно, Parsec , в котором есть хорошее руководство пользователя , в котором объясняется, как его использовать. Существует список портов этой библиотеки для других языков (включая C ++ и Ruby ), перечисленных на странице Parsec вики Haskell , хотя я не знаком с ними, и поэтому я не могу сказать, насколько они близки к использованию Parsec в Haskell.

Если вы хотите узнать, как они работают внутренне и как писать свои собственные, я рекомендую начать с главы 8 («Функциональные парсеры») из Грэма Хаттона «Программирование на Haskell ». Как только вы хорошо поймете эту главу (которая, вероятно, займет несколько чтений), вы будете готовы.

2 голосов
/ 28 июня 2009

Давайте создадим компилятор - пошаговое руководство по написанию простого компилятора. Код написан на Delphi (Pascal), но он достаточно прост, чтобы его можно было легко перевести на большинство других языков.

1 голос
/ 17 июля 2009

Вот учебник по автономному (10 страниц!) Полностью портативному компилятору-компилятору которые могут быть использованы для очень быстрого проектирования и реализации DSL с «низкими издержками»:

http://www.bayfronttechnologies.com/mc_tutorial.html

Этот сайт знакомит вас с документом Вала Шорре 1964 года о MetaII. Да, 1964. И это удивительно. Вот как я узнал о компиляторах в 1970 году.

1 голос
/ 28 июня 2009

Забавное время: сегодня я провел много времени, размышляя о конечных автоматах и ​​синтаксических анализаторах и пытаясь выяснить, как можно узнать о них больше.

Для 2 вы можете взглянуть на Ragel (это хорошо для C ++ и Ruby).

1 голос
/ 28 июня 2009

Определение грамматики с использованием BNF, EBNF или чего-либо подобного проще, и в дальнейшем вам будет легче поддерживать ее. Также вы можете найти множество примеров грамматических определений. И последнее, но не менее важное: если вы собираетесь поговорить о своей грамматике с кем-то еще на поле, лучше, если вы оба говорите на одном языке (BNF, EBNF и т.

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

Для C ++ я бы также предложил lex / yacc. Для Ruby это выглядит как достойный выбор: Coco / R (uby)

1 голос
/ 28 июня 2009

В Perl, модули Parse :: RecDescent - это первое место для запуска. Добавьте учебное пособие к названию модуля, и Google сможет найти множество учебников, чтобы вы могли начать работу.

...