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 :

Liste chaînée (compilation)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 33
    Par défaut Liste chaînée (compilation)
    Bonsoir,

    Dans le cadre d'un projet de compilation, je bute sur la réalisation de l'arbre syntaxique abstrait (plus précisément sur les liste de déclaration de variables, arguments, fonctions) mais je pense que mon problème est indépendant du contexte.

    Voici des extraits de mon code qui seront je l'espère suffisants :

    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
    42
    43
     
    n_l_dec *listedeclVariables(){
        n_dec *tete = NULL;
        n_l_dec *queue = NULL;
        if (syntout) out("<listedeclVariables>\n");
        tete = declVariable();
        //TEST
        printf("TEST 1 : %s\n", tete->nom);
        //TEST
        queue = listedeclVariablesBis();
        if (syntout) out("</listedeclvariables>\n");
        //TEST
        printf("TEST 2 : %s\n", tete->nom);
        //TEST
        return cree_n_l_dec(tete, queue);
    }
     
    n_l_dec *listedeclVariablesBis(){
        n_dec *tete = NULL;
        n_l_dec *queue = NULL;
        if (syntout) out("<listedeclVariablesBis>\n");
        if (cc == ','){
            cc = yylex();
            tete = declVariable();
            queue = listedeclVariablesBis();
        }
        if (syntout) out("</listedeclvariablesBis>\n");
        return cree_n_l_dec(tete, queue);
    }
     
    n_dec *declVariable(){
        n_dec *variable = NULL;
        if (syntout) out("<declVariable>\n");
        if (cc == ENTIER){
            cc = yylex();
            if (cc == ID_VAR){
                variable = cree_n_dec_var(yylval.string);
                cc = yylex();
            }
        }
        if (syntout) out("</declVariable>\n");
        return variable;
    }
    Et les structures utilisées dans ce extrait :

    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
     
    struct n_l_dec_{
      n_dec *tete;
      struct n_l_dec_ *queue;
    };
     
    n_l_dec *cree_n_l_dec(n_dec *tete, n_l_dec *queue);
     
    struct n_dec_ {
      enum{foncDec, varDec, tabDec} type;
      char *nom;
      union {
        struct{n_l_dec *param; n_l_dec *variables; n_instr *corps;}foncDec_;
        struct{int type;}varDec_;
        struct{int taille;}tabDec_;
      } u;
    //u n'est pas utilisé dans le cas d'une variable
    };
     
    n_dec *cree_n_dec_var(char *nom);
    Voila, mon soucis est que au lieu de me retrouver avec une liste chainée dans laquelle je peux circuler avec une boucle while, j'ai seulement une instance (qui correspond à la dernière variable analysée).
    par exemple dans la première fonction, le premier test affiche bien la première variable mais le deuxième affiche la dernière (j'espère que je suis assez clair...)

    N'étant pas très au fait de la portée des variables en c, je pense que le problème vient de là, sans en être certain.

    Je vous remercie d'avance de preter attention à mon problème, en espérant que vous pourrez me fournir des pistes pour le résoudre.

    Bonnes fêtes,

    Cordialement,

    Adrien.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Par défaut
    Ca va être très compliqué de voir ton problème sans le code de remplissage de la liste.

    Ton appel récursif de listedeclVariablesBis ne semble pas correcte : comment lies-tu les éléments de la liste entre-eux ?
    J'ai l'impression que tu créés un élément sans le lier au précédent.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 33
    Par défaut
    Tout d'abord, merci d'avoir pris le temps de me répondre,

    Il y a clairement un problème de ce genre vu le retour de cette fonction !

    La liste est justement censée être remplie par cette fontion listedeclVariablesBis().

    En effet pour moi (et c'est surement là que je mérite des coups de baton) :
    lors de l'appel récursif, vu que le retour de la fonction est un maillon de la liste stocké dans la variable queue de l'appel précédent, au fur à mesure que les appels imbriqués se terminent, la liste se construit.

    Je devrais donc pouvoir régler le problème en passant le maillon précédent en paramètre de la fonction et en créant le maillon dont l'élément queue est initialisé à NULL avant l'appel récursif ?

    Je vais tester cela, mais dans tous les cas, et pour éviter de futures erreurs, je suis curieux de savoir pourquoi ce code ne marche pas comme je l'attendais !

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Par défaut
    Citation Envoyé par adrienmgs Voir le message
    En effet pour moi (et c'est surement là que je mérite des coups de baton) :
    lors de l'appel récursif, vu que le retour de la fonction est un maillon de la liste stocké dans la variable queue de l'appel précédent, au fur à mesure que les appels imbriqués se terminent, la liste se construit.
    C'est ca ton souci, ce que tu fais n'est pas une liste chainée.

    Citation Envoyé par adrienmgs Voir le message
    Je devrais donc pouvoir régler le problème en passant le maillon précédent en paramètre de la fonction et en créant le maillon dont l'élément queue est initialisé à NULL avant l'appel récursif ?
    Oui, c'est mieux.
    Comment relies-tu les noeuds entre eux ?
    Sans tenir compte de "tete", une liste chainée c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct n_dec_ {
      enum{foncDec, varDec, tabDec} type;
      char *nom;
      union {
        struct{n_l_dec *param; n_l_dec *variables; n_instr *corps;}foncDec_;
        struct{int type;}varDec_;
        struct{int taille;}tabDec_;
      } u;
    //u n'est pas utilisé dans le cas d'une variable
      struct n_dec_ *psuivant;
    };
    ta structure doit contenir un pointeur sur elle-même.
    http://chgi.developpez.com/pile/

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 33
    Par défaut
    ok donc en fait dans la configuration actuelle toutes les instances sont perdues sauf la dernière ;p

    Mais en fait la liste chainée est de type n_l_dec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct n_l_dec_{
      n_dec *tete;
      struct n_l_dec_ *queue;
    };
    Elle contient donc bien un pointeur sur l'élément suivant ?

    n_dec est le type de donnée "porté" par le maillon de la liste.

    donc en fait ma fonction listedecVariableBis() renvoie une liste chainée qui est censée venir ce greffer à la suite de celle créée lors des appels précédents de cette fonction, mais au lieu de cela, la liste renvoyée écrase la précédent à chaque appel, ce qui fait que cette liste ne contient toujours qu'un maillon.

    Je vais essayer de reprendre tout ça après avoir lu ton lien, je pense que je me fais une mauvaise représentation du fonctionnement des liste chainées.

    Merci de ton aide !

  6. #6
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Par défaut
    Non, tu n'as pas fait une liste chainée !!
    Tu as une structure qui pointe sur la tête de la liste et sur un élément de cette liste, donc rien n'est chainé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Compiler une liste chaînée
    Par jvb55 dans le forum Débuter
    Réponses: 9
    Dernier message: 30/03/2013, 00h34
  2. Réponses: 1
    Dernier message: 19/03/2011, 18h30
  3. Réponses: 3
    Dernier message: 23/09/2010, 17h05
  4. Réponses: 15
    Dernier message: 01/11/2005, 13h32
  5. Insertion d'un noeud dans une liste chaînée
    Par habib106 dans le forum Assembleur
    Réponses: 8
    Dernier message: 07/04/2004, 22h34

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