IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[C#] Parser code source C avec regex


Sujet :

C#

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Aspic
    Homme Profil pro
    �tudiant
    Inscrit en
    Ao�t 2005
    Messages
    3 905
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (�le de France)

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �lectronique et micro-�lectronique

    Informations forums :
    Inscription : Ao�t 2005
    Messages : 3 905
    Par d�faut [C#] Parser code source C avec regex
    Bonjour � tous,

    Je souhaiterais parser un code source C classique afin de r�cup�rer les fonctions et le mettre dans un tableau :
    Code c : 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
     
    // Exemple de code source à parser
    void 
    a(int p1, float p2)
    {
     
    }
     
    void b()
    {
        int p1=5;
        float p2 = 10.0;
        a(p1,p2);
    }
     
    int main()
    {
        int p1=5;
        float p2 = 10.0;
        a(p1,p2);
        b();
    }
    Je voudrais isoler chaque bloc de fonction et le mettre en m�moire :
    tab[0] = "void
    a(int p1, float p2)
    {

    }"

    tab[1] = "void b()
    {
    int p1=5;
    float p2 = 10.0;
    a(p1,p2);
    }"

    tab[2] = "int main()
    {
    int p1=5;
    float p2 = 10.0;
    a(p1,p2);
    b();
    }"
    Je ne suis pas du tout dou� avec les regex, je sais utiliser la classe Regex en C# mais pour trouver l'expression r�guli�re c'est autre chose

    Je pense qu'il faut d�finir un pattern du genre :
    (type_retour|void) (espaces|tabulations|saut ligne) nom_fonction (espaces|tabulations|saut ligne) (param�tres) (espaces|tabulations|saut ligne)
    {
    DU TEXTE
    }


    Enfin, je ne suis m�me pas sur. Pouvez vous m'aider ?

    Merci d'avance
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  2. #2
    Membre confirm�

    Homme Profil pro
    Ing�nieur int�gration
    Inscrit en
    Juillet 2009
    Messages
    62
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activit� : Ing�nieur int�gration

    Informations forums :
    Inscription : Juillet 2009
    Messages : 62
    Par d�faut
    Je pense que l'approche via les les expressions r�guli�res ne soit pas la plus adapt�e pour ce type de probl�matique.

    Il faut plut�t voir du cot� des parsers/analyseurs de textes tel que ANTLR

    A voir Tutoriel sur la mise en place d'une grammaire avec ANTLR

  3. #3
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par d�faut
    Pour la regex on peut tenter mais �a ne fonctionnera pas forc�ment. Le probl�me est que sans information de contexte on peut seulement chercher les formes "identifiant + identifiant + parenth�se gauche". Or m�me s'il ne m'en vient pas � l'esprit il y a peut-�tre des ambigu�t�s, notamment du c�t� du pr�processeur (et comment g�rer ce dernier d'ailleurs ?). Et si des infos de contexte sont n�cessaires alors la regex ne peut pas g�rer �a et il faut un parser "� pile" (pense au parsing d'expressions mises entre parenth�ses).

    Autres contraintes: quid du code malform� et des caract�res exotiques? Je doute que le C suive les cat�gories d'unicode, qui ne devait m�me pas exister � l'�poque. Donc les cat�gories regex pourraient ne pas coller.

    Tout d�pend donc des sources � parser et de ce qu'on veut exactement mais la regex peut se r�v�ler insuffisante. Dans ce cas on peut tenter d'�crire un parsing manuel incluant un comptage de parenth�ses (ce qui peut-�tre simple si on ne veut parser qu'une petite partie). Ou bien avoir recours � un parser generator comme sugg�r� par le moussel. Mais outre que cela ajoute une d�pendance au projet, leur utilisation est malheureusement souvent fastidieuse et t'imposera d'apprendre le fonctionnement d'un g�n�rateur de parser. Un comble ! Cela dit c'est une comp�tence utile.


    Si au vu des contraintes que j'ai �num�r�es la regex peut fonctionner alors il suffit de concat�ner comme suit :
    Identifiant: \w[\w\d]*
    Espaces, tab et sauts de ligne: ([\s\n]|(\r\n))*
    Pour le d�but: (\w[\w\d]*|void)

  4. #4
    Membre Expert
    Avatar de Aspic
    Homme Profil pro
    �tudiant
    Inscrit en
    Ao�t 2005
    Messages
    3 905
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (�le de France)

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �lectronique et micro-�lectronique

    Informations forums :
    Inscription : Ao�t 2005
    Messages : 3 905
    Par d�faut
    Bonsoir,

    Effectivement il semble que l'approche regex ne soit pas la bonne.
    Alors j'avais d�j� vu du c�t� de ANTLR mais il faudrait des semaines pour comprendre comment ca marche et cela rajoute une d�pendance au projet.

    Au final m�me si le style de code � parser reste simple (on part du principe que le code est correct syntaxiquement et avec une imbrication { et } parfaite), je ne vois pas comment r�gler le probl�me des accolades � l'int�rieur d'une fonction.

    Exemple :
    Code c : 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
    void b()
    {
        int p1=5;
        float p2 = 10.0;
        a(p1,p2);
        if ( blabla) {
    
        }
        else {
            while (blabla)
            {
    
            }
        }
    } // <--- il faudrait s'arr�ter � cette accolade d�s qu'on a match� le prototype de la fonction...
    
    float autre_fonction() {}
    Impossible de dire avec une regex, je dois m'arr�te � la "bonne" accolade (celle qui ferme la fonction)

    Ou alors j'ai loup� quelque chose...

    Merci � vous
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  5. #5
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    D�tails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par d�faut
    Effectivement une regex ne peut traiter des structures r�cursives (tu peux bidouiller si la profondeur max de la r�cursion est connue et faible). J'avais zapp� le fait que tu voulais �galement capturer le corps. Tu pourrais toujours bidouiller en utilisant la regex pour capturer l'en-t�te puis utiliser une proc�dure manuelle pour trouver l'accolade de fin. Resteraient quand m�me le probl�me du pr�processeur et celui des cha�nes de caract�res qui pourraient contenir des accolades ou des motifs �quivalents � des en-t�tes de fonction.

    Bref, la regex est limit�e mais avec un peu de bricolage et des sources simples �a peut marcher. Une solution manuelle sera un peu plus puissante mais � nouveau elle �chouera face � certains cas particuliers, sauf � y passer beaucoup de temps pour cr�er un parser complet. Quant � antlr �a ne prend pas des semaines et �a reste la fa�on la plus rapide d'avoir un parser 100% compatible.

    Tout d�pend des sources. Si tu peux bricoler, bricole.

  6. #6
    Membre Expert
    Avatar de Aspic
    Homme Profil pro
    �tudiant
    Inscrit en
    Ao�t 2005
    Messages
    3 905
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (�le de France)

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �lectronique et micro-�lectronique

    Informations forums :
    Inscription : Ao�t 2005
    Messages : 3 905
    Par d�faut
    Citation Envoy� par DonQuiche Voir le message
    Resteraient quand m�me le probl�me du pr�processeur et celui des cha�nes de caract�res qui pourraient contenir des accolades ou des motifs �quivalents � des en-t�tes de fonction.
    Pour le pr�processeur, � tout hasard ca ne serait pas possible de r�cup�rer un code interm�diaire o� les #define sont remplac�s juste avant la compilation ? (je pense � une option de gcc qui permettrait de sortir un fichier en code C mais avec une passe du pr�processeur ?)

    Pour les accolades dans une chaine de caract�res, j'ai avait pens� on ne peut pas les virer avec une regex ? Voire m�me virer tout le texte dans les guillemets ? Exemple : printf("je fais foirer le parser { ahahahah"); devient printf(""); ou alors printf();
    Citation Envoy� par DonQuiche Voir le message
    Quant � antlr �a ne prend pas des semaines et �a reste la fa�on la plus rapide d'avoir un parser 100% compatible.
    Un jour, j'apprendrais ce nouvel outil, ca � vraiment l'air pas mal mais au premier abord (en regardant le tuto sur DVP), cela avait l'air compliqu�...
    Pour l'instant �tant donn� que les sources sont simples, je continue en mode bricolage m�me si c'est pas bien � termes j'en suis conscient

    Citation Envoy� par Mat.M
    Ensuite l� o� je me suis arrach� les cheveux de la t�te c'est pour d�limiter les blocs avec les accolades.
    Tu m'�tonnes, je suis entrain de p�ter un c�ble dessus actuellement
    C'est clair que du VB.net aurait �t� plus simple
    Citation Envoy� par Mat.M
    Maintenant si on souhaite d�limiter les blocs il faut empiler les blocs � l'aide d'une pile ; les blocs de fonctions et d'expressions d�limit�s par des accolades doivent �tre symm�triques �videmment.
    Une pile permet de restituer le dernier �l�ment empil�.
    Alors une pile, j'avais eu l'id�e mais je n'ai pas trouv� comment faire au final. D�s que je trouve une accolade ouvrante, j'empile le code lu pr�c�demment (de la pr�c�dente accolade ouvrante jusqu'� celle que je viens de trouver) et que je trouve une accolade fermante, je d�pile le dernier �l�ment mais au final comment reconstituer les blocs ?
    Avec un arbre binaire, je ne vois simplement pas comment on pourrait faire.
    Citation Envoy� par Mat.M
    ce que j'ai fait dans mon projet d'interpr�teur c'est que le code source initialement en Javascript ( syntaxe proche du C donc ) est compil� dans un pseudo-code ( un peu comme l'Intermediate Language de .NET) et comme �a il est interpr�t� lin�airement par le module d'ex�cution.
    C'est toi qui a cr�� le pseudo-code ? Si oui, comment as tu fait ? Et je suppose que parser le pseudo-code �tait plus facile que le code source d'origine ?

    PS : Au final, ton projet a �t� termin� � 100% ?

    Merci beaucoup.
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  7. #7
    Expert confirm�
    Avatar de Mat.M
    Profil pro
    D�veloppeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 539
    D�tails du profil
    Informations personnelles :
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 539
    Par d�faut
    Citation Envoy� par Aspic Voir le message
    Je souhaiterais parser un code source C classique afin de r�cup�rer les fonctions et le mettre dans un tableau :
    je te souhaite un bon courage c'est assez ardu � faire...
    j'avais commenc� � faire un interpr�teur de langage genre Javascript,langage C pour mon projet ( que je souhaite commercialiser..) mais un jour j'ai vite chang� pour faire un interpr�teur BASIC.

    Ceci dit si je peux essayer de donner des tuyaux je peux
    Je n'utilise pas du tout les expressions r�guli�res.
    J'analyse caract�re par caract�re pour voir si c'est un espace, un chiffre...
    Ensuite l� o� je me suis arrach� les cheveux de la t�te c'est pour d�limiter les blocs avec les accolades.
    En Basic c'est plus facile �tant donn� que �a finit avec End Sub ou End Function
    Maintenant si on souhaite d�limiter les blocs il faut empiler les blocs � l'aide d'une pile ; les blocs de fonctions et d'expressions d�limit�s par des accolades doivent �tre symm�triques �videmment.
    Une pile permet de restituer le dernier �l�ment empil�.


    Citation Envoy� par Aspic Voir le message
    Au final m�me si le style de code � parser reste simple (on part du principe que le code est correct syntaxiquement et avec une imbrication { et } parfaite), je ne vois pas comment r�gler le probl�me des accolades � l'int�rieur d'une fonction.

    s
    pour analyser et d�limiter les blocs on peut aussi �ventuellement utiliser un arbre binaire; chaque noeud de l'arbre est en fait un bloc du source : par exemple pour une condition if , pour une boucle etc...

    ce que j'ai fait dans mon projet d'interpr�teur c'est que le code source initialement en Javascript ( syntaxe proche du C donc ) est compil� dans un pseudo-code ( un peu comme l'Intermediate Language de .NET) et comme �a il est interpr�t� lin�airement par le module d'ex�cution.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Code source projet avec CORBA
    Par mourad1987 dans le forum CORBA
    R�ponses: 1
    Dernier message: 30/04/2012, 13h13
  2. R�ponses: 0
    Dernier message: 07/10/2011, 14h17
  3. parser code source jave pour obtenir un AST
    Par cdm1024 dans le forum G�n�ral Java
    R�ponses: 1
    Dernier message: 10/08/2009, 09h19
  4. R�ponses: 6
    Dernier message: 19/07/2007, 12h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo