Как разобрать / просто проанализировать код C / C ++ из C #, чтобы получить список методов - PullRequest
6 голосов
/ 11 января 2012

Мне нужно пройти через файл C / C ++ и извлечь список классов и методов и их расположение в файле.

Является ли libclang лучшим вариантом?Или это «слишком много» для задачи?

Было бы лучше просто искать парные скобки?

В случае выбора libclang: есть ли способ вызвать его из c #?

Спасибо!

Ответы [ 6 ]

6 голосов
/ 11 января 2012

Можно рассмотреть ctags , доступных на многих платформах. Вывод легко разбирается и содержит всю необходимую вам информацию.

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

ctags -N -x --c-kinds=+p crowd.*

производит этот вывод

CrowdSim         class        44 crowd.h          class CrowdSim
CrowdSim         function     47 crowd.h          CrowdSim( const std::string& contentDir ) : _contentDir( contentDir ) {}
Particle         function     35 crowd.h          Particle()
Particle         struct       25 crowd.h          struct Particle
_contentDir      member       56 crowd.h          std::string _contentDir;
_crowd_H_        macro        18 crowd.h          #define _crowd_H_
_particles       member       57 crowd.h          std::vector< Particle > _particles;
animTime         member       32 crowd.h          float animTime;
chooseDestination function     24 crowd.cpp        void CrowdSim::chooseDestination( Particle &p )
chooseDestination prototype    53 crowd.h          void chooseDestination( Particle &p );
dx               member       28 crowd.h          float dx, dz; // Destination position
dz               member       28 crowd.h          float dx, dz; // Destination position
fx               member       29 crowd.h          float fx, fz; // Force on particle
fz               member       29 crowd.h          float fx, fz; // Force on particle
init             function     35 crowd.cpp        void CrowdSim::init()
init             prototype    49 crowd.h          void init();
node             member       31 crowd.h          H3DNode node;
ox               member       30 crowd.h          float ox, oz; // Orientation vector
oz               member       30 crowd.h          float ox, oz; // Orientation vector
px               member       27 crowd.h          float px, pz; // Current postition
pz               member       27 crowd.h          float px, pz; // Current postition
update           function     68 crowd.cpp        void CrowdSim::update( float fps )
update           prototype    50 crowd.h          void update( float fps );

(примечание: -x только для удобства проверки пользователем)

4 голосов
/ 11 января 2012

Чтобы сделать это хорошо, вам действительно нужно нечто, содержащее полный синтаксический анализатор C ++.

Можно использовать наш набор инструментов для реинжиниринга программного обеспечения DMS с C ++ Front End за это.Он может предоставлять как точные объявления сущностей, включая типы, так и их контекст (класс / пространство имен / ...) и точные позиции файлов.DMS обеспечивает доступ ко всей этой информации в виде набора AST и связанных таблиц символов;Вы создаете пользовательский код для перехода к / брать то, что вы хотите.

В зависимости от ваших потребностей, вы можете обнаружить, что нужную информацию сложно обработать с использованием vanilla C #.Информация о типах во всей своей красе довольно сложна, потому что C ++ - сложный язык.Если вы хотите обработать эту информацию, вам нужно «оставаться внутри» DMS, где присутствует весь механизм, который это делает.Если вам нужны только имена и информация о типе в виде текстовых строк, вы можете заставить DMS красиво распечатать эти данные в этой форме;у него есть стандартные библиотеки, поддерживающие такие действия.Промежуточным ответом будет экспорт данных в формате XML;DMS обеспечивает прямую поддержку экспорта произвольных фрагментов AST, но только косвенную поддержку для записи информации о типах в виде XML, но это не составит труда настроить.

РЕДАКТИРОВАТЬ: (в ответ на комментарий OP в другом ответе) DMSможет предоставить точную информацию как о сигнатуре метода, так и о теле метода.Он имеет полный AST и тип информации для обоих.

1 голос
/ 20 февраля 2014

Если вы хотите использовать Clang, я рекомендую вам взглянуть на эту страницу .Он демонстрирует, как получить все виртуальные методы из файла.Как только вы поймете этот простой пример, вы сможете создавать более сложные так называемые сопоставители.

1 голос
/ 11 января 2012

Другим углом будет создание расширения для Visual Studio.

1 голос
/ 11 января 2012

Не уверен, что это лучший вариант, но вы также можете посмотреть GCC-XML или Mono / CXXI ​​. Последний использует GCC-XML для внутреннего использования, но также предоставляет интерфейсы C # для определений классов C ++.

libclang - это библиотека C, поэтому ее можно использовать из .NET через P / Invoke, но повторение всех необходимых объявлений в C # может быть довольно утомительным.

0 голосов
/ 11 января 2012

Лучше использовать полноценный парсер IMO. Вы можете использовать ANTLR . Он имеет как грамматику C / C ++, так и генератор синтаксического анализа C #.

...