Варианты разбора / обработки файлов C ++ - PullRequest
4 голосов
/ 07 февраля 2012

Поэтому мне нужно иметь возможность анализировать некоторые относительно простые файлы C ++ с аннотациями и генерировать из них дополнительные исходные файлы.

Например, у меня может быть что-то вроде этого:

//@ service
struct MyService
{
   int getVal() const;
};

Мне нужно найти аннотацию // @ service и получить описание структуры, которая следует за ней.

Я смотрю на возможное использование LLVM / Clang, так как, похоже, есть поддержка библиотек длявстраивание функций компилятора / синтаксического анализа в сторонние приложения.Но я действительно довольно невежествен в том, что касается синтаксического анализа исходного кода, поэтому я не уверен, что именно мне нужно искать, или с чего начать.

Я понимаю, что AST - это ядроязыковые представления, и есть поддержка библиотеки для создания AST из исходных файлов в Clang.Но комментарии не будут частью права AST?Итак, что было бы хорошим способом найти представление структуры, которая следует за конкретной аннотацией комментария?

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

Ответы [ 3 ]

4 голосов
/ 07 февраля 2012

Один из способов, которыми я занимался, - это аннотировать идентификаторы:

  • классы
  • базовые классы
  • учеников
  • 1010 * перечисления *
  • 1012 * счетчикам *

например:.

class /* @ann-class */ MyClass 
    : /* @ann-base-class */ MyBaseClass
{
    int /* @ann-member */ member_;
};

Такая аннотация позволяет легко написать скрипт на python или perl, который читает строку заголовка построчно и извлекает аннотацию и связанный идентификатор.

Аннотация и связанный идентификатор позволяют генерировать отражение C ++ в форме шаблонов функций, которые пересекают объекты, передавая базовые классы и члены функтору, например:

template<class Functor>
void reflect(MyClass& obj, Functor f) {
    f.on_object_start(obj);
    f.on_base_subobject(static_cast<MyBaseClass&>(obj));
    f.on_member(obj.member_);
    f.on_object_end(obj);
}

Также удобно генерировать числовые идентификаторы (перечисления) для каждого базового класса и члена и передавать их функтору, например:

    f.on_base_subobject(static_cast<MyBaseClass&>(obj), BaseClassIndex<MyClass>::MyBaseClass);
    f.on_member(obj.member_, MemberIndex<MyClass>::member_);

Такой код отражения позволяет писать функторы, которые сериализуют и десериализуют любой тип объекта в / из ряда различных форматов. Функторы используют перегрузку функций и / или вывод типов для правильной обработки различных типов.

2 голосов
/ 07 февраля 2012

Разбор кода C ++ - чрезвычайно сложная задача.Использование компилятора C ++ может помочь, но может быть полезно ограничить себя более менее специфичным для домена форматом, т. Е. Генерировать исходные и дополнительные файлы C ++ из более простого представления, например, прото-файлов protobuf s или WSDL SOAP илиеще проще в вашем конкретном случае.

1 голос
/ 15 апреля 2013

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

Остальные ответы недействительны при разборе кода C ++. Мне нужно что-то, что могло бы правильно обработать ~ 90% кода C ++; В итоге я использовал srcML . Этот инструмент берет исходный код C ++ или Java и преобразует его в документ XML, что упрощает его анализ. Это держит комментарии в такте. Кроме того, если вам нужно выполнить преобразование исходного кода, он поставляется с обратным инструментом, который возьмет XML-документ и выдаст исходный код.

Он работает в 90% случаев правильно, но он связан со сложным метапрограммированием шаблонов и самыми темными углами синтаксического анализа C ++. К счастью, мой исходный код довольно последовательный по дизайну (не так уж много хитростей в C ++), поэтому он работает для нас.

Другие элементы для просмотра включают gcc-xml и reflex (который фактически использует gcc-xml). Я не уверен, сохраняет ли GCC-XML комментарии или нет, но он сохраняет атрибуты и прагмы GCC.

Последний пункт, на который стоит обратить внимание, - это блог о написании плагинов GCC, написанный автором инструмента CodeSynthesis ODB.

Удачи!

...