Bonjour,
je cherche à faire un petit parseur de code C qui retrouve les prototypes des fonctions.
Je me suis fait le code suivant :et j'obtiens ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 def findall ( exp,str ): '''Renvoie une liste de dict de toutes les occurrences de exp dans la chaîne str (re.findall ne fait pas ce que je veux)''' res,pos = [],0 while True : match = exp.search( str[pos:],re.DOTALL ) if not match : return res pos += match.end()-1 res += [ match.groupdict() ] def find_all_proto ( source ): '''Renvoie tous les prototypes C de source''' regx = r'''(\W|\A) (?P<type> (\w+ ( \* | \s+ )+ )+ ) (?P<name> \w+ ) \s*\( (?P<param> .*? ) \) \s* ;''' ex_proto = re.compile( regx,re.DOTALL+re.VERBOSE) return findall( ex_proto,source ) def test_find_proto (): s = '''void f1 (); void f2 ( void ) ; void f3( int x );void f4 ( int x , char * s ); void*f5 ( int x , char * s ); void* f6 ( int x , char * s ); void *f7 ( int x , char * s ); void * f8 ( int x , char * s ); int ** f9 ( int x , char * s ); int * * f10 ( int x , char * s ); int * ** f11 ( int x , char * s ); const int * ** f12 ( int x , char * s ); const int*const **f13 ( int x , char * s ); const int f14 ( int x , char * s ); static const int f15 ( int x , char * s ); ''' for p in find_all_proto( s ): print '%-20s : %3s : %s'%(p.get('type'),p.get('name'),p.get('param','')) test_find_proto()Comme vous pouvez le voir il me manque presque une fonction sur 2, à part les 13 et 15 dont il manque le premier mot.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void : f2 : void void : f4 : int x , char * s void* : f6 : int x , char * s void * : f8 : int x , char * s int * * : f10 : int x , char * s const int * ** : f12 : int x , char * s int*const ** : f13 : int x , char * s int : f14 : int x , char * s const int : f15 : int x , char * s
Si je supprime la fin de l'expression régulièrej'obtiens ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 regx = r'''(\W|\A) (?P<type> (\w+ ( \* | \s+ )+ )+ ) (?P<name> \w+ ) \s*\('''Cette fois, j'ai bien toutes les fonctions et il ne manque aucun mot.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 void : f2 : void : f3 : void* : f5 : void* : f6 : void * : f7 : void * : f8 : int ** : f9 : int * * : f10 : int * ** : f11 : const int * ** : f12 : const int*const ** : f13 : const int : f14 : static const int : f15 :
A part "f1" et "f4" qui manquent encore.
Donc, à vous les experts des reg exp : comment expliquer un tel comportement ?
Encore plus étrange :
Si j'ajoute une première ligne à mes prototypes de test, le résultat dépend du nombre de caractères :j'ai bien "f1" mais je perds "f2" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 def test_find_proto (): s = '''zzzzz void f1 (); ....Mais avec un 'z' de moins, je pers à nouveau "f1".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 void : f1 : void : f3 : void* : f5 : void* : f6 : void * : f7 : void * : f8 : ...
Si quelqu'un a une idée... moi je suis à sec !
Merci !
Partager