gcc для разбора кода - PullRequest
       2

gcc для разбора кода

5 голосов
/ 16 ноября 2011

Я хотел бы знать, как использовать GCC в качестве библиотеки для анализа кода C / C ++ / Java / Objective C / Ada для моей программы.Я хочу обойти предварительную обработку и префикс всех функций, которые пользователь написал с префиксом My.например, Print(); становится MyPrint(); Я также хочу сделать это с переменными.

Ответы [ 6 ]

3 голосов
/ 16 ноября 2011

Вы можете посмотреть здесь:
http://codesynthesis.com/~boris/blog/2010/05/03/parsing-cxx-with-gcc-plugin-part-1/

Это описание того, как использовать интерфейс плагина gcc для анализа кода C ++. С другим языком следует обращаться таким же образом.

Также вы можете попробовать свинину из Mozilla:
https://wiki.mozilla.org/Pork

Когда я попробовал это (свинина), я потратил час или около того, чтобы исправить проблемы компиляции, но потом Я могу написать сценарии, как это:

rewrite SyncPrimitiveUpgrade {
  type PRLock* => Mutex*
  call PR_NewLock() => new Mutex()
  call PR_Lock(lock) => lock->Lock()
  call PR_Unlock(lock) => lock->Unlock()
  call PR_DestroyLock(lock) => delete lock
}

так что он нашел все типы PRLock и переписал их с Mutex, также он ищет вызов функций например, PR_NewLock и заменить его на «новый Mutex».

2 голосов
/ 16 ноября 2011

Наш инструментарий реинжиниринга программного обеспечения DMS может анализировать код C, C ++, Java и Ada (не Objective C в настоящее время) в широком спектре диалектов и выполнять преобразования в коде. Внешние интерфейсы DMS C и C ++ включают препроцессор, поэтому вы можете вызвать предварительную обработку перед анализом.

Я, вероятно, не понимаю, что вы хотите сделать, потому что кажется странным переименовывать каждую функцию и (глобальную?) Переменную с префиксом "My ....". Но вы могли бы сделать это с некоторыми правилами DMS (грубый набросок переименований пользовательских функций для GCC3:

domain C~GCC3.

rule rewrite_function_names(t: type_designator, i: IDENTIFIER, p: parameter_list, s: statements):
      function_header->functionheader
"\t \i(\p) { \s } " -> "\t \renamed\(\i\) (\p) { \s }" ;

и вспомогательная функция «переименовывает», которая принимает узел дерева, содержащий идентификатор, и возвращает узел дерева с переименованным идентификатором.

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

Вам потребуются некоторые дополнительные шаблоны для обработки различных синтаксических случаев в каждом языке (например, для C, возвращаемый тип «void», потому что «void» не является указателем типа в синтаксисе и объявлениями глобальных переменных) и разные правила для разных языков (синтаксис Ada отличается от синтаксиса языка C).

Это может показаться большим ударом для вашей задачи, но если вы действительно настаиваете на том, чтобы делать это для различных языков надежным способом, то, похоже, трудно избежать проблемы получения достойных парсеров для всех этих языков. (И если вы действительно собираетесь сделать это для всех этих языков, DMS можно научить работать с ObjectiveC так же, как мы учили его для других языков).

Ваша альтернатива - какое-то решение для взлома строк, которое может работать 95% времени. Если вы можете жить с этим, то Perl или что-то подобное, скорее всего, ваш ответ.

2 голосов
/ 16 ноября 2011

забудьте о GCC, он сделан как анализатор компилятора, а не анализатор анализа, вам лучше использовать что-то вроде libclang , интерфейс C для clang , который может обрабатывать как C & C ++

2 голосов
/ 16 ноября 2011

Во-первых, GCC не является библиотекой и не структурирован как единая (в отличие от LLVM).

Почему (то есть для чего) вы хотите анализировать исходный код C, C ++, Ada?

Я бы посчитал (при условии, что версия GCC 4.6 ) расширяет GCC либо через плагины, написанные на C, либо предпочтительно с использованием MELT , высокойязык уровня домена для расширения GCC (отказ от ответственности: я являюсь основным автором MELT).

Но использование GCC в качестве библиотеки вообще нереально.

Я действительно думаю, что для того, что выхочу достичь, MELT это правильный инструмент.Однако, это плохо документировано.Пожалуйста, используйте список gcc-melt@googlegroups.com, чтобы задавать вопросы.

И помните, что расширение GCC требует некоторого объема работы (возможно, больше недели), потому что вам необходимо частично понять внутреннее представление GCC.

2 голосов
/ 16 ноября 2011

Для C вы не можете сделать это надежно.Если вы пропустите предварительную обработку, то, как правило, у вас не будет действительного кода C для анализа.Например,

#define FOO
#define BAR
#define BAZ

FOO void BAR qux BAZ(void) { }

Как синтаксический анализатор должен распознавать это определение функции qux без предварительной обработки?

2 голосов
/ 16 ноября 2011

Возможно, вы захотите исследовать синтаксический анализатор разреженный C.Он понимает много C (все C, используемые в исходных кодах ядра Linux, что является довольно хорошим подмножеством допустимых расширений ANSI-C и GNU-C) и предоставляет несколько примеров бэкэндов компилятора для обеспечения lint -подобный инструмент статического анализа для проверки типов.

Хотя код выглядит очень чистым и тщательным, ваша задача может быть легче выполнена с помощью другого механизма - example.c, включенного в источник sparse, которыйдемонстрирует компилятор длиной 1955 строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...