Получить имена всех вызываемых функций (C++)

Модератор: Модераторы разделов

Аватара пользователя
Atragor
Сообщения: 681
Статус: ...

Получить имена всех вызываемых функций

Сообщение Atragor »

Вот такое задание: дан код на C++, надо вывести имена всех вызываемых функций с номерами строк, в которых происходят вызовы. Со всякими for(... и if(..., которые не есть функции, и прочей мелочью я уже разобрался, но остались проблемы с тем, например, как отличать вызов функции от объявления. Может кто-нибудь знает, где можно украсть посмотреть такой алгоритм? Вопрос адресован пользователям KDevelop, Eclipse и прочих IDE.

Я начинаю подозревать, что учесть все особенности C++ будет сложно :unsure:
If you were MEANT to understand it, we wouldn't have called it 'code' © bash.org
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Получить имена всех вызываемых функций

Сообщение sergio »

Atragor писал(а):
24.05.2008 23:30
Я начинаю подозревать, что учесть все особенности C++ будет сложно :unsure:

Мне кажется, что для этого нужно не особенности учитывать, а очень добротный и полноценный парсер. Регекспами отличить вызов функции от использования функтора или создания объекта (с тем же именем, но в другом неймспейсе) будет, боюсь, затруднительно. :)
как отличать вызов функции от объявления. Может кто-нибудь знает, где можно украсть посмотреть такой алгоритм?

Какой-то "такой" алгоритм использует, по всей вероятности, доксиген. И, кажется, с него даже можно было стрясти структуру (перл), описывающую в неком дереве все то, что он считал по файлам сорса. Другие варианты еще менее децкие - отодрать парсер от GCC, например. ;) Или изучить, какие мета-структуры в нем передаются между слоями...
Словом, Atragor, если бы эта задача была такая решаемая - у нас было бы много хороших ИДЕ для плюсоа. А в реальности, перед разработчиками ява была поставлена задача, в частности, построить язык так, чтобы с ним справлялись средства авто-докуметирования, обратного проектирования и пры. Потому что плюсы с этой задачей стыкуются, очевидно, плоховато. ;)
Поэтому реалистичных вариантов два: или допустить, что решение вам нужно не всегда работающее, а чаще всего работающее. :) Либо поискать такой функционал где-то готовый или почти готовый для пользования. Например в виме с емаксом поспрашать.
Кстати, никто не понял, боюсь, на каком языке или чем вы собираетесь учитывать все особенности Си++, и почему обращаетесь к пользователям ИДЕ.

Зы. А вызов функции от объявления отличается объявлением возвращаемого типа... других отличий может не оказаться в наличии...
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
Аватара пользователя
Atragor
Сообщения: 681
Статус: ...

Re: Получить имена всех вызываемых функций

Сообщение Atragor »

sergio писал(а):
25.05.2008 00:00
Кстати, никто не понял, боюсь, на каком языке или чем вы собираетесь учитывать все особенности Си++, и почему обращаетесь к пользователям ИДЕ.


На нем же.
Я просто предположил, что в какой-нибудь IDE есть подобный функционал.
За ответ спасибо.

sergio писал(а):
25.05.2008 00:00
Зы. А вызов функции от объявления отличается объявлением возвращаемого типа... других отличий может не оказаться в наличии...

А возвращаемый тип может к тому же быть абсолютно произвольным, в том числе и пользовательским.

P.S. Вот ведь влип... Видимо наш препод решил написать новую IDE для плюсов и переложил часть работы на студентов :)
If you were MEANT to understand it, we wouldn't have called it 'code' © bash.org
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Получить имена всех вызываемых функций

Сообщение sergio »

Atragor писал(а):
25.05.2008 00:06
sergio писал(а):
25.05.2008 00:00
Кстати, никто не понял, боюсь, на каком языке или чем вы собираетесь учитывать все особенности Си++, и почему обращаетесь к пользователям ИДЕ.

На нем же.

Совсем злоъ. :) Злее уж не бывает. Он точно хочет полноценный парсер. Потому что приблизительный результат делать надо на перле, есессно. А на плюсах - знач хочет все как у больших. ))))

Я просто предположил, что в какой-нибудь IDE есть подобный функционал.

Генераторы парсеров есть. Называются что-то вроде bison и yacc, если мне память не изменяет. На ГСС 3 первое время был такой, потом его переписали ручками. Можете покопать в эту сторону...

sergio писал(а):
25.05.2008 00:00
Зы. А вызов функции от объявления отличается объявлением возвращаемого типа... других отличий может не оказаться в наличии...

А возвращаемый тип может к тому же быть абсолютно произвольным, в том числе и пользовательским.

А это не важно. Если не делать все оч серьезно, то это не важно. Главное, что он есть. :)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: Получить имена всех вызываемых функций

Сообщение Portnov »

C++ одними только lex/yacc, насколько я помню, не разбирается. Если действительно надо полностью парсить код, попробуйте использовать парсер от g++ (у него есть опции, чтоб вывести дерево разбора и еще какие-то промежуточные представления). Другой вариант - попробовать программы, специально заточенные под "браузинг кода". CScope, например, приходит в голову.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
Аватара пользователя
whirlwind
Сообщения: 67

Re: Получить имена всех вызываемых функций

Сообщение whirlwind »

есть программа ctags (она же, возможно, etags), которая список всех функций и идентификаторов, которые есть в файле. Вроде именно она используется внутри KDevelop и прочих сред
Добро всегда побеждает зло. Мы победили, значит мы - добро.
Спасибо сказали:
Аватара пользователя
Electronix
Сообщения: 53
ОС: Slackware, Suse, XP

Re: Получить имена всех вызываемых функций

Сообщение Electronix »

Товарищи - yacc и lex - это Си, для С++ есть это же только гораздо удобнее и лучше называется библиотека boost::spirit.

whirlwind
К сожалению - ctags этого не выдает.

Вообще все понятно - препод увидел CScope, эта такая штука для Си (для с++ KScope), вообщем там как раз можно получить то что хочет автор, НО это работает только с Си кодом - простым, в котором только вызов функций. Как уже заметили сейчас есть все возможные функторы, указатели на функции класса итд итп. Ну и самое главное конечно - виртуальные методы, тут никакой парсер не поможет, потому что вызванный метод определяется во время выполнения, а не компиляции.
Задача практически не выполнимая для исходного кода. Есть специальные программы профилировщики, кажется в них есть возможность показать все вызванные функции (если они были вызваны во время работы), но они работают уже с бинарником,а не исходных кодом.
Вообщем, даже у MSVS + VAX + CodeRush (в IDE для linux, чтобы такой функционал получить - нужно работать еще лет 5, без сна и обеда), нету подобного - так что не огорчайся, это слишком сложно и нету ни одной такой программы для С++.

Вообщем мой совет - спроси у препода, как он себе предоставляет реализацию такой программы и не забудь подкрепить те аргументы, которые здесь в ветке приведены - если он не сумашедший он должен будет тебе упростить задание, ограничить рамками.
We have no beginning, we have no end. We are infinite.
Спасибо сказали:
Аватара пользователя
Atragor
Сообщения: 681
Статус: ...

Re: Получить имена всех вызываемых функций

Сообщение Atragor »

Electronix писал(а):
27.05.2008 15:27
Вообщем мой совет - спроси у препода, как он себе предоставляет реализацию такой программы и не забудь подкрепить те аргументы, которые здесь в ветке приведены - если он не сумашедший он должен будет тебе упростить задание, ограничить рамками.


Да я уже сам себя ограничил :) Вроде работает и даже вызовы выводит, если сильно её не мучать. Думаю для защиты хватит. А по поводу виртуальных методов - вряд ли нужно получать список фактически вызываемых функций, скорее всего выводить нужно все, что похоже на вызов, то есть если где-то в тексте написано "func();", то вывести вне зависимости от того, вызывается ли она при выполнении программы или нет.

Всем спасибо, тему можно закрывать.
If you were MEANT to understand it, we wouldn't have called it 'code' © bash.org
Спасибо сказали: