2010-02-09 3 views
0

Compte tenu du nom de la fonction et du nombre de paramètres de la fonction, comment lister toutes les définitions de fonctions en utilisant egrep et regex?Comment rechercher des fonctions avec un certain nombre de paramètres

Par exemple, le nom de la fonction est « trouver » nous attendions à ce que ces fonctions « trouver » qui ont seulement trois paramètres, ni plus ni moins comme ce qui suit:

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

J'essaie pour résoudre le problème par moi-même comme:

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

mais cela ne fonctionne pas. J'ai donc besoin de votre aide pour indiquer ce qui ne va pas avec la regex que j'ai utilisée et donnez-moi votre solution au problème "name: find number of parameters: 3" si possible.

+0

Quelle langue est-ce? –

+0

@Chris: C++. mais le type de langue n'est pas important dans mon cas. Je veux juste à tous les endroits (dans un nom de fichier :: ligne de manière numérique) répond au patern que j'ai mentionné. –

Répondre

5

Utiliser des regex n'est pas fiable, doublement pas avec egrep, sauf si vous suivez certaines conventions et ne faites rien de trop dur.

Tenir compte:

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

Cette déclaration est répartie sur 6 lignes - et egrep regarde seulement une ligne à la fois.

Cette déclaration contient 5 virgules et 3 paramètres.

Si vous mettez suffisamment de restrictions sur le code que vous recherchez, vous pouvez probablement obtenir une approximation de ce que vous recherchez, mais C et C++ sont tous deux très difficiles à analyser. Et je ne pense même pas aux macros qui invoquent la fonction pour vous.


Votre solution proposée a un certain nombre de défauts, même après avoir résolu le problème avec les antislashs étrangers (correctement diagnostiquée par Tim Pietzcker):

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

Cela découvrir des lignes telles que:

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) */ 

Une seule de ces fonctions est une définition de fonction, et ce n'est toujours pas l'une des sorties que vous vouliez. Si vous pouvez jouer avec Perl (ou Python) ou n'importe quel outil avec PCRE (Perl-Regular Regular Expressions) ou équivalent, vous pouvez faire en sorte que sur une seule ligne apparaisse le mot 'find' suivi d'un parenthèse ouvrante, une séquence de valeurs 'nom de type' séparées par des virgules et des espaces, et une parenthèse fermante.

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

Mais qui ne gère pas les pointeurs, les tableaux, des qualificatifs comme « const », ou des pointeurs vers les fonctions (ou des références, si vous utilisez C++), ou structures référencées par « struct somename varname », ou la fonction définitions protégées contre la macro-expansion (int (getchar)(int c)), ou ... Et il ne fait toujours pas de distinction entre les déclarations et les définitions!

2

Vous échappez à la * où vous ne devriez pas parce que c'est vraiment un quantificateur ici - maintenant vous essayez de faire correspondre l'astérisque littéralement. Mais vous devriez échapper aux parenthèses.

Alors:

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

fonctionnerait mieux, mais - comme Jonathan Leffler a écrit - qui ne fonctionne que dans un sous-ensemble très petit nombre de cas possibles, vous devriez peut-être penser une approche différente.

1

Que diriez-vous d'une expression rationnelle, comme suit (Perl):

trouver \ s + \ (\ s * \ w + \ s + \ w +, \ s * \ w + \ s + \ w +, \ s * \ w + \ s + \ w + \)

?

+0

Clôturer - voir les réponses apportées (que j'ai générées pendant que vous étiez en train d'ajouter le vôtre). Votre expression régulière trouve 'extra_find (int i, int j, int k)' ce qui n'est pas strictement ce que l'on veut. (Mais alors, aucune des autres réponses ne fait exactement ce qui est requis.) –

Questions connexes