code_analyzer/prez.md
2022-01-08 16:57:10 +01:00

2.6 KiB

Mon projet est le projet sous le numero 38 qui est analyse d'un programme.

Dans quel sens un "programme" ?

Un programme au sens de code source d'un programme qui comporte plusieurs fichier et plusieurs centaines / milliers de lignes de code. Ce code doit etre interpreté sous forme d'un graphe orienté avec un vecteur de successeur et un graphe a matrice compacte.

Pour exemple, voici un programme avec plusieur fichiers (174) et plusieurs milliers de lignes de code (300347).

Le code est parsé ligne par ligne contre 2 regex. Le premier pour les definitions des fonctions et le deuxieme pour les appels des fonctions.

Apres la construction des graphes, une des taches etait de cherches des composantes connex dans ces graphes.

Une CC dans un code est une fonction qui appele plusieurs autres fonctions. Par exemple la fonction main est une composante connexe. Et une fonction qui n'est pas appelé par main ou ses successeurs est consideré comme une autre CC.

Pour ce faire, je pensais d'abord faire un algo de recherche, car sur internet si on cherche des info sur le sujet, ils parlent de faire un algo. Comme c'est moi qui construit le graphe, je peux deduire qui est une CC et qui n'en est pas.

J'ai donc introduit une variable call dans mes stucture pour dire si une fonction (noeud) a été appelé ou pas. Puis, j'ai une variable vu, qui dis si lors de print d'un noeud (main), on a vu cette fontion. Et donc toute fonction qui etait pas vu peut etre une CC.

L'etape suivante etait de trouver des cycles des appels de fonctions. Voici un exemple de cycle. On voit que la fonction bar appele la fonction toto qui appel la fonction foo qui reappel la fonction bar.

Pour la recherche de cycles, j'ai utilisé l'algo DFS (Deep First Search / recherche en profondeur).

J'ai trouvé un pseudo-code sur internet que j'ai utilisé et adapté pour mes structures. Dans le pseudo-code il y a 3 algorithmes.

Dans le premier on parcour le graph, pour chaque noeud on crée une pile vide, on push le noeud courrant dans la pile, on dis que le noeud est dans la stack et on fait un DFS dedans.

Deuxieme algo est le DFS. Pour chaque successeur dans le noeud on regarde s'il est visité ou dans la pile. Si le successeur est dans la pile, ca veut dire qu'on a trouvé un cycle. Donc on affiche le cycle. Si le successeur est pas encore visité, on le push dans la stack en indiquant qu'il est desormais dans la stack, et on appele recursivement DFS pous ce successeur.

A la fin on indique qu'on a fini avec le noeud et on pop la derniere valeur de la pile.

Dans le troisieme algo on print le cycle.