Получить разрешение имен в проекте C ++ - PullRequest
0 голосов
/ 27 апреля 2018

Задача

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

int x = 0;
int y = x + 1;

Используя разрешение имен для переменной x второго оператора, я обнаруживаю, что он объявлен в первом.

Текущее решение

Во-первых, я использовал плагин Eclipse CDT (только часть CDT) для создания абстрактных синтаксических деревьев (AST). Более ясно, что каждый из файлов исходного кода в проекте тестирования анализируется для создания соответствующего AST. Однако эти AST не содержат разрешения имен. Поэтому я должен проанализировать AST, чтобы определить разрешение имен. Мое текущее решение кажется хорошим, но для крупномасштабных проектов и сложных структур оно определенно дает сбой.

Позже я знал, что информацию о разрешении имен можно получить автоматически с помощью Eclipse CDT. Но мне нужно создать автономный инструмент (вне Eclipse), это означает, что я не смог интегрировать свой инструмент в CDT.

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

Обновлено (на основе рекомендаций ниже)

Некоторые предлагают мне следующее и мой ответ.

+ Использовать Clang

Это правда, что Clang поддерживает анализ файлов C ++ (и файлов C тоже), и никто не отрицает, что Clang - хороший выбор. Тем не менее, я хочу использовать мой язык Java . В настоящее время я нахожу только один (например, Eclipse CDT плагин). Как я уже сказал, плагин CDT не поддерживает разрешение имен, когда я пытаюсь использовать его вне Eclipse CDT IDE.

Мой текущий автономный инструмент Java, а именно CFT4Cpp , использует плагин CDT для анализа программы на C / C ++. Из-за ограничения CDT плагина, я проанализировал разрешение имен, используя несколько простых алгоритмов. Однако эти алгоритмы не работают при анализе сложных проектов с точки зрения синтаксиса.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

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

C ++ теперь постоянно меняющийся язык. Начиная с C++11, дорожная карта является новой версией стандарта каждые 3 года. И им это надоело: у нас есть C ++ 11, C ++ 14, C ++ 17 и C ++ 20 на ходу.

Впереди у вас будет очень сложная и трудоемкая задача только из-за изменений в стандарте.

Например, я показываю вам только 1 изменение на версию, для которой вам нужно будет добавить поддержку. Можете ли вы / вы хотите полностью поддерживать каждую новую стандартную версию? Или вы собираетесь получить приложение / инструмент, который к моменту выхода из разработки уже устарел?

C ++ 98:

int x = 0;
int y = x + 1;

C ++ 11:

auto x = 0;
auto y = x + 1;

C ++ 14

[](auto x) { auto y = x; }

C ++ 17

if (const auto [iter, inserted] = mySet.insert(value); inserted)

C ++ 20, надеюсь, это:

template <class T, class F, class P>
   requires requires(T x, F f, P p) {
       f(x);
       {p(f(x))} -> bool;
   }
auto bar(T x, F f, P p)
{
   //
}

С помощью решения, основанного на компиляторе, таком как gcc или clang, вы все это позаботились самим компилятором. Все, что вам нужно сделать, это использовать его в своих целях.

0 голосов
/ 27 апреля 2018

C ++ является очень сложным языком программирования (и отличается от C). Разбор это очень трудная задача ( много лет работы - возможно, всю жизнь, если работать в одиночку - если вы делаете это с нуля).

Итак, создайте свой инструмент на основе существующей технологии синтаксического анализа C ++ . Вы можете использовать GCC , возможно, через GCC плагины или Clang (см. this ) или Edison C ++ Свободное программное обеспечение Компиляторы C ++ - это огромные звери (несколько миллионов строк), которые постоянно развиваются и растут, и для их освоения требуется много работы. Кстати, вы можете использовать обычные межпроцессные коммуникации (например, JSONRPC или другие подходы) или интерфейсы сторонних функций методы (например, JNI ) использовать компиляторы C ++ из Java.

Однако я хочу использовать язык Java.

Будьте прагматичны. Так что кодируйте небольшую часть в C ++ (над существующими синтаксическими анализаторами, например, из компиляторов C ++), а остальные - в Java.

(для академического прототипа использование некоторого межпроцессного взаимодействия между адаптированным компилятором в C ++ и некоторым инструментом в Java, вероятно, является менее трудным, однако вам придется кодировать несколько тысяч строк на стороне компилятора в C ++, поскольку C ++ сложен, и вам нужно больше на стороне Java; кстати, вам, вероятно, нужно немного попрактиковаться в C ++, чтобы иметь возможность создавать полезные вещи для него ...)

(поскольку вы, вероятно, не найдете полных компиляторов C ++ или внешних интерфейсов в Java)

Даже если создать свою вещь выше существующего синтаксического анализатора C ++, задача не из легких и может занять несколько месяцев вашего времени. И существующие синтаксические анализаторы C ++ развиваются (например, внутренние представления GCC слегка меняются от одной версии к следующей). Так что вам нужно составить бюджет на развитие этих парсеров.

А синтаксический анализ C ++ сам по себе является плохо определенной задачей (подумайте о предварительной обработке, расширении шаблонов и т. Д ....). Вам необходимо определить, в какой форме представления кода, связанного с C ++, вы хотите работать. Конечно, стандарт C ++ имеет несколько выпусков и т. Д.

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

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

Другой подход (который работает в Linux, но, вероятно, не везде) - попросить вашего пользователя скомпилировать с включенной отладочной информацией (например, с g++ -g, если он использует GCC ) и проанализировать DWARF отладочная информация.

Кстати, я работал над похожими целями: несколько лет назад в GCC MELT , а теперь в моем bismon github проекте (временное имя будет меняться). Не забудьте получить финансирование на несколько лет работы на полную ставку, так как ваша цель очень амбициозна.

...