Как искать функции с определенным количеством параметров - PullRequest
0 голосов
/ 09 февраля 2010

Учитывая имя функции и количество параметров, которые имеет функция, как вывести список всех определений функции с помощью egrep и regex?

Например, имя функции «найти», мыожидается, что функции "find" найдут только три параметра, не больше и не меньше, как показано ниже:

sometype find ( type1 para1 , type2 para 2 , type3 para 3 )

Я пытаюсь решить проблему самостоятельно:* но это не работает.Поэтому мне нужна ваша помощь, чтобы указать, что не так с регулярным выражением, которое я использовал, и дать мне ваше решение проблемы «имя: найти число параметров: 3», если это возможно.

Ответы [ 3 ]

5 голосов
/ 09 февраля 2010

Использование регулярных выражений ненадежно, вдвойне не с egrep, если вы не следуете некоторым соглашениям и не делаете ничего слишком сложного.

Рассмотрим:

void *
function(
    int a,
    void (*pointer)(const char *, int, double),
    double d
)

Это объявление распространяется на 6 строк, и egrep просматривает только одну строку за раз.

Это объявление содержит 5 запятых и 3 параметра.

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


Предлагаемое вами решение имеет ряд недостатков, даже после решения проблемы с посторонними обратными слешами (правильно диагностирован Тимом Пицкером):

egrep "find" * | egrep "\([^,]*,[^,]*,[^,]*\)"

Это откроет такие строки, как:

find(1, 2, 3);
int extra_find(int a, int b, int c) { ... }
extraordinary(find, 3, 21);
printf("find: %.*s\n", 13, "heliotrope");
for (find(1); printf("%d %d\n", 1, 2); x++)
for (x(find, 1); b < max(c, d); i++)
/* find(1,2,3) */

Только одним из них является определение функции, и это все еще не тот выход, который вы хотели.

Если вы можете играть с Perl (или Python) или любым инструментом с PCRE (регулярными выражениями, совместимыми с Perl) или аналогичными, то вы можете сделать что-то, например, убедиться, что на одной строке появляется слово «найти» с последующим открытием скобка, последовательность значений «имя типа», разделенных запятыми и пробелами, и закрывающая скобка.

perl -ne 'print if m/\bfind\s*\(\w+\s+\w+(\s*,\s*\w+\s+\w+){2}\s*\)/'

Но это не относится к указателям, массивам, квалификаторам, таким как 'const', или указателям на функции (или ссылкам, если вы используете C ++), или структурам, на которые ссылается "struct somename varname", или определениям функций, защищенным от макросов расширение (int (getchar)(int c)) или ... И оно по-прежнему не различает объявления и определения!

2 голосов
/ 09 февраля 2010

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

Итак:

\([^,]*(,[^,]*){2}\)

будет работать лучше, но - как писал Джонатан Леффлер - это будет работать только в очень небольшом подмножестве возможных случаев, поэтому вам следует подумать о другом подходе.

1 голос
/ 09 февраля 2010

Как насчет регулярных выражений, таких как следующий (Perl):

найти \ S + \ (\ с * \ ш + \ s + \ ш + \ с * \ ш + \ s + \ ш + \ с * \ ш + \ s + \ ш + \)

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