Хорошие инструменты для создания анализатора / анализатора C / C ++

Какие хорошие инструменты для быстрого начала анализа и анализа кода на C / C ++?

В частности, я ищу инструменты с открытым исходным кодом, которые обрабатывают препроцессор и язык C / C ++. Предпочтительно, эти инструменты будут использовать lex / yacc (или flex / bison) для грамматики, а не быть слишком сложными. Они должны обрабатывать последние определения ANSI C / C ++.

Вот что я нашел до сих пор, но не смотрел на них подробно (мысли?):

  • CScope – анализатор С-старой школы. Тем не менее, похоже, что он не выполняет полный анализ. Описан как прославленный «grep» для нахождения функций C.
  • GCC – любимый компилятор с открытым исходным кодом. Очень сложно, но, похоже, все это. Существует связанный с этим проект для создания расширений GCC под названием GEM , но он не обновлялся после GCC 4.1 (2006).
  • PUMA – PUre MAnipulator. (со страницы: «objective этого проекта – предоставить библиотеку classов для анализа и управления источниками C / C ++. Для этого PUMA предоставляет classы для сканирования, parsingа и, конечно, манипулирования источниками C / C ++».) , Это выглядит многообещающим, но не обновлялось с 2001 года. Очевидно, PUMA была включена в AspectC ++ , но даже этот проект не обновлялся с 2006 года.
  • Различные исходные грамматики C / C ++. Вы можете получить c-c ++ – grammars-1.2.tar.gz , но это было сохранено с 1997 года. Небольшой поиск в Google подтягивает другие базовые грамматики lex / yacc, которые могут служить стартовым местом.
  • Любые другие?

Я надеюсь использовать это как отправную точку для перевода источника C / C ++ в новый язык игрушек.

Благодаря! Матф

(Добавлено 2/9): Просто пояснение: я хочу извлечь семантическую информацию из препроцессора в дополнение к самому коду C / C ++. Я не хочу, чтобы «#define foo 42» исчезал в целое число «42», но оставался прикрепленным к имени «foo». Это, к сожалению, исключает несколько решений, которые сначала запускают препроцессор и только доставляют дерево синтаксического анализа C / C ++)

Синтаксический анализ C ++ чрезвычайно сложный, поскольку грамматика неразрешима. Процитировать Йосси Крейнину :

Выдающаяся сложная грамматика

«Превосходно» следует толковать буквально, потому что все популярные языки имеют контекстно-бесплатные (или «почти» контекстно-свободные) грамматики, в то время как C ++ имеет неразрешимую грамматику. Если вам нравятся компиляторы и парсеры, вы, вероятно, знаете, что это значит. Если вы не занимаетесь подобным делом, есть простой пример, показывающий проблему с синтаксическим анализом C ++: это AA BB(CC); определение объекта или объявление функции? Оказывается, ответ в значительной степени зависит от кода перед заявлением – «контекста». Это показывает (на интуитивном уровне), что грамматика C ++ вполне контекстно-зависимая.

Вы можете посмотреть на clang, который использует llvm для синтаксического анализа.

Поддержка C ++ полностью сейчас

Генератор парсеров ANTLR имеет грамматику для C / C ++, а также препроцессор. Я никогда не использовал его, поэтому не могу сказать, насколько полным будет его синтаксический анализ C ++. ANTLR сам по себе полезный инструмент для меня несколько раз для анализа более простых языков.

В зависимости от вашей проблемы GCCXML может быть вашим ответом. В основном он анализирует источник с помощью GCC, а затем дает вам легко усваиваемый XML дерева parsingа. С GCCXML вы делаете раз и навсегда.

pycparser – полный синтаксический анализатор для C (C99), написанный на Python. Он имеет полностью настраиваемую базу данных AST, поэтому он используется в качестве основы для любого вида обработки языка, который может вам понадобиться.

Однако не поддерживает C ++. Конечно, это намного сложнее, чем C.


Update (2012) : на этот раз ответ, без всякого сомнения, будет Clang – он модульный, поддерживает полный C ++ (со многими функциями C ++ – 11) и имеет относительно дружественную базу кода. Он также имеет C API для привязки к языкам высокого уровня (т.е. для Python ).

Посмотрите, как работает Doxygen , доступен полный исходный код и он основан на flex.

Недопустимым кандидатом является GOLD, который представляет собой бесплатный инструментарий парсера для Windows, явно предназначенный для создания переводчиков. Их список поддерживаемых языков относится к языкам, на которых можно реализовать парсеры, а не список поддерживаемых грамматик parsingа.

У них есть только грамматики для C и C #, нет C ++.

Разбор C ++ – очень сложная задача .

Есть структура Boost / Spirit, и пару лет назад они играли с идеей реализации парсера C ++ , но это далеко не полный .

Полностью и правильно parsing ISO C ++ далек от тривиального, и на самом деле было много связанных усилий. Но это сложная задача, которая нелегко выполнить, не переписывая полный интерфейс компилятора, понимающий все C ++ и препроцессор. Предпроцессорная реализация, называемая «волной», доступна от людей Spirit.

Тем не менее, вы можете захотеть взглянуть на свинину / oink (на основе elsa), которая представляет собой набор инструментов синтаксического анализатора C ++, специально предназначенный для использования в целях преобразования исходного кода, и он используется проектом Mozilla для крупномасштабных статический анализ исходного кода и автоматическое переписывание кода, самая интересная часть заключается в том, что он не только поддерживает большую часть C ++, но и сам препроцессор!

С другой стороны, есть действительно одно единственное доступное решение: интерфейс EDG, который можно использовать для почти всех связанных с C ++ усилий.

Лично я бы рассмотрел комплект свиней / оник, основанный на elsa, который используется в Mozilla, кроме того, FSF теперь одобрила работу над gcc-плагинами с использованием лицензии библиотеки времени выполнения, поэтому я бы предположил, что все изменится быстро, как только люди могут легко использовать gcc-based C ++ parser для таких целей, используя двоичные плагины.

Итак, в двух словах: если у вас есть деньги: EDG, если вам нужно что-то бесплатное / open source сейчас : else / oink довольно перспективны, если у вас есть время, вы можете использовать gcc для своего проекта.

Другой вариант только для C-кода – cscout .

Грамматика для C ++ – это своего рода печально известный волосатый. В Lambda есть хорошая нить, но суть в том, что грамматика C ++ может потребовать сколь угодно большого внимания.

Для того, что я могу себе представить, я бы подумал о том, чтобы взломать Gnu CC или Splint . Gnu CC, в частности, довольно подробно выделяет часть генерации языка, поэтому вам может быть лучше создать новый g ++-сервер.

На самом деле PUMA и AspectC ++ по-прежнему активно поддерживаются и обновляются. Я изучал использование AspectC ++ и задавался вопросом об отсутствии обновлений самостоятельно. Я отправил электронное письмо автору, который сказал, что и AspectC ++, и PUMA все еще разрабатываются. Вы можете получить исходный код через SVN https://svn.aspectc.org/repos/ или вы можете получить регулярные бинарные сборки на http://akut.aspectc.org . Как и в настоящее время с множеством отличных проектов на C ++, у автора нет времени, чтобы не отставать от обслуживания веб-страниц. Имеет смысл, если у вас есть полная работа и жизнь.

Elsa превосходит все остальное, что я знаю, руки для синтаксического анализа C ++, хотя это не соответствует 100%. Я – фанат. Там есть модуль, который печатает C ++, так что это может быть хорошей отправной точкой для вашего игрушечного проекта.

как насчет чего-то более легкого для понимания, как крошечный-C или Small C

См. Наш C ++ Front End для полнофункционального анализатора C ++: строит AST, таблицы символов, разрешает имя и тип. Вы можете даже анализировать и сохранять директивы препроцессора. Передняя часть C ++ построена поверх нашего инструментария DMS Software Reengineering Toolkit , который позволяет вам использовать эту информацию для выполнения произвольных изменений исходного кода с использованием преобразований источника в источник.

DMS – идеальный двигатель для внедрения такого переводчика.

Сказав это, я не вижу большого смысла в вашей воображаемой задаче; Я не вижу большой ценности в попытке заменить C ++, и вы найдете для построения полного переводчика огромную работу, особенно если ваша цель – «игрушечный» язык. И, вероятно, мало смысла в синтаксическом анализе C ++ с использованием сильного парсера, если его единственная цель – создать изоморфную версию C ++, которая проще разобрать (подождите, мы уже постулировали прочный C ++ уже!).

EDIT Май 2012: интерфейс DMS C ++ теперь обрабатывает GCC3 / GCC4 / C ++ 11, Microsoft VisualC 2005/2010. Надёжная.

EDIT Feb 2015: теперь обрабатывает C ++ 14 в GCC и MS-диалектах.

EDIT Август 2015: теперь анализирует и фиксирует как код, так и директивы препроцессора в едином дереве.

Некоторое время назад я попытался написать инструмент, который будет автоматически генерировать модульные тесты для c-файлов.

Для preprosessing я помещал файлы через GCC. Результат является уродливым, но вы можете легко отслеживать, где в исходном коде из предварительно обработанного файла. Но для ваших нужд вам может понадобиться что-то еще.

Я использовал Meter в качестве основы для C-парсера. Он является открытым исходным кодом и использует lex и yacc. Это позволило легко встать и запустить за короткое время без полного понимания lex & yacc.

Я также написал приложение C, так как решение lex & yacc не могло помочь мне отслеживать функциональность функций и анализировать структуру всей функции за один проход. Вскоре он был незаметным и был оставлен.

Что же касается использования инструмента, такого как CFlow от GNU, который может анализировать код и создавать диаграммы графиков вызовов, вот что говорит opengroup (man-страница) о cflow. GNU-версия cflow поставляется с источником, а также с открытым исходным кодом …

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

  • Может ли class Java добавлять метод вовремя?
  • Обнаружение пикового сигнала в реальном времени
  • Лучшие способы анализа URL с помощью C?
  • Как анализировать информацию из дампа ядра Java?
  • Правильно Разбор JSON в Swift 3
  • JSON Parsing in Swift 3
  • Параметры сопоставления CSV с .NET
  • Что такое амортизированный анализ алгоритмов?
  • Соответствующее математическое выражение с регулярным выражением?
  • LINQ Ring: Any () vs Содержит () для огромных коллекций
  • : непризнанный селектор, отправленный в экземпляр
  • Давайте будем гением компьютера.