Partage
  • Partager sur Facebook
  • Partager sur Twitter

Créer mon langage

Implémentation suggestion

Sujet résolu
    4 mai 2023 à 19:24:10

    Je souhaite crée mon langage est est déjat fait la partie Lexicale. Mai je doit maintenant choisir comment implémenté l’analyse de syntax. Voici mon code actuel (Ceci est une démo pour montré le concept): 

    #include <stdio.h>
    enum type{
        Ident,
        OEF,
        Virgule,
        Egual,
        LParent,
        RParent,
        LParagra,
        RParagra,
        Value
    }type;
    
    #define SizeTableau 200
    
    int main()
    {
        int t=0;
        int thing[SizeTableau]={Ident,Egual,Value,Ident,Ident,LParent,RParent,LParagra,LParagra,RParagra,RParagra,Ident,Egual,Value,OEF};
        do
        {
            if(thing[t]==Ident)
            {
                t++;
                printf("\nIdent");
                if(thing[t]==Ident)
                {
                    printf(": est un Type\nIdent: est une foncion");
                    t++;
                    if(thing[t]==LParent)
                    {
                        t++;
                        printf("\nLParent");
                        if(thing[t]==RParent)
                        {
                            t++;
                            printf("\nRParent");
                        }
                    }
                }
                else if(thing[t]==Egual)
                {
                    printf(": Est Une variable\nEgual");
                    t++;
                    if(thing[t]==Value)
                    {
                        printf("\nValue");
                        t++;
                    }
                }
            }
            else if(thing[t]==LParagra)
            {
                t++;
                printf("\nLParagra");
            }
            else if(thing[t]==RParagra)
            {
                t++;
                printf("\nRParagra");
            }
            else if(thing[t]==OEF)
            {
                t=0;
                printf("\nOEF");
            }
            else
            {
                printf("\nSyntax Error");
                t++;
            }
            if(t>=SizeTableau)
            t=0;
        }while(t);
    
        return 0;
    }

    Pensé vous que cette implémentation pose un problème est avais vous des suggestion?

    -
    Edité par sdms 4 mai 2023 à 21:14:09

    • Partager sur Facebook
    • Partager sur Twitter
      5 mai 2023 à 16:15:27

      Hello !

      sdms a écrit:

      est déjat fait la partie Lexicale. 

      Lexicale ? Je ne vois que des constantes, qui en dehors du code n'auront plus rien de Lexicale.
      • Partager sur Facebook
      • Partager sur Twitter
        5 mai 2023 à 16:21:33

        En faite c'est que ce n'est qu'une démo ici pour le concepts. Il faut bien pensé que le programme est divisé en réalité en plusieurs partie. La première partie divise le code source en plusieurs jeton appeler "Token"; ce sont les différent mots clée variable fonction etc.... En fonction du langage, ces jeton sont identifier par ces fameuse constante. La démo n'est ici que pour une preuve de concept.

        -
        Edité par sdms 5 mai 2023 à 16:25:26

        • Partager sur Facebook
        • Partager sur Twitter
          5 mai 2023 à 19:28:01

          > Pensé vous que cette implémentation pose un problème est avais vous des suggestion?

          Ca n'implémente pas grand chose ton truc.


          Si tu veux nous convaincre que c'est une preuve de concept (quel concept ?), montre que ça tourne (c'est censé faire quoi ?) sur plusieurs exemples.



          Si c'est pour initialiser comme ça

          int thing[SizeTableau]={Ident,Egual,Value,Ident,Ident,LParent,RParent,LParagra,LParagra,RParagra,RParagra,Ident,Egual,Value,OEF};
           

          ça serait plus logique que ça soit


          type thing[SizeTableau] = ....;
          


          Par ailleurs, tu pourrais utilement employer un switch à la place d'une forêt de if.

          Sinon, pour l'analyse syntaxique, une descente récursive est souvent la solution la plus simple pour construire des analyseurs à la main. voir https://www.google.com/search?q=descente+recursive

          Pour en dire plus, il faudrait avoir une description précise de la syntaxe voulue.

          -
          Edité par michelbillaud 5 mai 2023 à 20:29:50

          • Partager sur Facebook
          • Partager sur Twitter
            6 mai 2023 à 15:59:05

            michelbillaud a écrit:

            > Pensé vous que cette implémentation pose un problème est avais vous des suggestion?

            Ca n'implémente pas grand chose ton truc.


            Si tu veux nous convaincre que c'est une preuve de concept (quel concept ?), montre que ça tourne (c'est censé faire quoi ?) sur plusieurs exemples.



            Si c'est pour initialiser comme ça

            int thing[SizeTableau]={Ident,Egual,Value,Ident,Ident,LParent,RParent,LParagra,LParagra,RParagra,RParagra,Ident,Egual,Value,OEF};
             

            ça serait plus logique que ça soit

            type thing[SizeTableau] = ....;
            


            Par ailleurs, tu pourrais utilement employer un switch à la place d'une forêt de if.

            Sinon, pour l'analyse syntaxique, une descente récursive est souvent la solution la plus simple pour construire des analyseurs à la main. voir https://www.google.com/search?q=descente+recursive

            Pour en dire plus, il faudrait avoir une description précise de la syntaxe voulue.

            -
            Edité par michelbillaud il y a environ 19 heures

            Bon, j'ai visiblement du mal à expliquer le concept de ma démo. oublier la si vous ne la comprenais pas.  Le concepts de récursivité est effectivement une bonne solution. C'est ce que je vais faire. Toutefois je cherche à le faire d'une façon différente car à chaque appel de fonction la pile est utilisé. J'ai peur de faire un dépassement de la pile. Mai j'ai peut être trouver un autre moyen de le faire. Chaque fonction utiliserai un pointeur de fonction quel affecterait à la fonction suivante. Alors ont sort de la fonction est en fait appel a l'autre fonction en utilisent le pointeur de fonction. De cette façon la pile n'est pas trop utilisé. Je vais voir si je peut faire comme ça.

            -
            Edité par sdms 6 mai 2023 à 15:59:49

            • Partager sur Facebook
            • Partager sur Twitter
              6 mai 2023 à 18:00:49

              Ça suppose que tu ne passeras pas de paramètre à tes fonctions appelées de cette façon.
              Tu peux le faire?
              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                6 mai 2023 à 19:07:02

                > à chaque appel de fonction la pile est utilisé. J'ai peur de faire un dépassement de la pile. Mai j'ai peut être trouver un autre moyen de le faire. Chaque fonction utiliserai un pointeur de fonction quel affecterait à la fonction suivante.

                Si tu trimballes des pointeurs de fonctions, la seule chose à quoi ça puisse te servir, c'est d'appeler les fonctions en question.

                Et ça utilise la pile, forcément.

                Bon courage pour écrire un interprète/compilateur qui n'utilise pas la récursivité qui te fait si peur :-)

                -
                Edité par michelbillaud 7 mai 2023 à 9:30:53

                • Partager sur Facebook
                • Partager sur Twitter
                  6 mai 2023 à 19:09:27

                  Oui. Il y a quelque façon de le faire. Je peut par exemple crée une variable dans la fonction qui fait appel au pointeur de fonction est la passer en paramètre à toute les autres fonctions qui peuvent alors communiquer entre elle. De la même manière je peut passer un pointeur sur une liste de différent type. Donc oui ces possible. Mai je n'est pas encore décidé comment je vais faire.

                  michelbillaud a écrit:

                  > r à chaque appel de fonction la pile est utilisé. J'ai peur de faire un dépassement de la pile. Mai j'ai peut être trouver un autre moyen de le faire. Chaque fonction utiliserai un pointeur de fonction quel affecterait à la fonction suivante.

                  Si tu trimballes des pointeurs de fonctions, la seule chose à quoi ça puisse te servir, c'est d'appeler les fonctions en question.

                  Et ça utilise la pile, forcément.

                  Bon courage pour écrire un interprète/compilateur qui n'utilise pas la récursivité qui te fait si peur :-)

                  -
                  Edité par michelbillaud il y a 2 minutes


                  oui ca utilise la pile mai seulement pour une profondeur de 1, puisque je revient à chaque fois au sommet. Et ce que j'essai de faire est en faite une récursivité émulé. Oui en fin j'essai :-°   

                  Je vien de comprendre pourquoi Michel me parler  de l’erreur type au lieu de int dans mon code, c'est corrigé. Voici ou j'en suis:

                  #include <stdio.h>
                  #define SizeTableau 200
                  
                  /*** Token identité ***/
                  typedef enum type{
                      Ident,
                      OEF,
                      Virgule,
                      Egual,
                      LParent,
                      RParent,
                      LParagra,
                      RParagra,
                      Value
                  }type;
                  
                  /*** structure pour pointé sur la fonction qui traite le prochain Token ***/
                  typedef struct NextToken NextToken;
                  
                  typedef struct NextToken{
                      int(*Next_token)(NextToken *NToken,type T);
                      type TokenType;
                      
                  }NextToken;
                  
                  /*** Les fonction qui traite les différent Token ***/
                  int noeuA(NextToken*, type);
                  int noeuB(NextToken*, type);
                  int noeuC(NextToken*,type);
                  
                  int main()
                  {
                      /*** liste des Token ***/
                      type thing[SizeTableau]={Ident,Egual,Value,OEF};
                  
                      NextToken Token;
                      Token.Next_token=noeuA;
                      Token.TokenType=thing[0];
                      int t=0;
                      
                      /*** execute les fonctions voulue suivont les différents tokens ***/
                      while(thing[t]!=OEF)
                      {
                          Token.Next_token(&Token,thing[t]);
                          t++;
                      }
                      return 0;
                  }
                  
                  int noeuA(NextToken* NToken,type t)
                  {
                      printf("test\n");
                      if(t==Ident)
                      NToken->Next_token=noeuB;
                      else
                      printf("erreur");
                      
                  }
                  int noeuB(NextToken *NToken,type t)
                  {
                      printf("test2\n");
                      if(t==Egual)
                      NToken->Next_token=noeuC;
                      else
                      printf("erreur");
                  }
                  int noeuC(NextToken *NToken,type t)
                  {
                      printf("test3\n");
                      
                  }



                  -
                  Edité par sdms 6 mai 2023 à 20:03:55

                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 mai 2023 à 1:08:53

                    As-tu une idée de la profondeur de tes récursivités?
                    J'imagine que les compilateurs actuels utilisent la récursivité.
                    Et même en Python, qui est un langage interprété, on peut aller par défaut jusqu'à un niveau de 1000 (+ ou - 2)

                    edit:

                    J'ai commis le programme stupide suivant:

                    #include <stdio.h>
                    int add(int n) {
                        if(n <= 0) return 0;
                        return n+add(n-1);
                    }
                    int main(void) {
                        int n;
                        scanf("%d", &n);
                        printf("%d\n", add(n));
                    }

                    Je me rend à plus de 43300 récursions sur Windows.

                    -
                    Edité par PierrotLeFou 7 mai 2023 à 3:36:16

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Le Tout est souvent plus grand que la somme de ses parties.

                      7 mai 2023 à 7:59:56

                      Le nombre de niveaux de récursion est à multiplier par la taille du "cadre de pile" qui contient les variables locales à chaque niveau (avec l’adresse de retour, celle du cadre précédent etc)

                      Si tu n'utilises pas la pile implicite des appels de fonction, tu te retrouves à placer tes données et pointeurs de fonction dans un gros tableau que tu vides/remplis  explicitement : c'est une pile aussi...

                      La boucle de la ligne 42 me fait penser que tu es en train de réinventer le "threaded code".

                      https://www.complang.tuwien.ac.at/forth/threaded-code.html

                      -
                      Edité par michelbillaud 7 mai 2023 à 10:26:31

                      • Partager sur Facebook
                      • Partager sur Twitter
                        7 mai 2023 à 10:45:07

                        michelbillaud a écrit:

                        Le nombre de niveaux de récursion est à multiplier par la taille du "cadre de pile" qui contient les variables locales à chaque niveau (avec l’adresse de retour, celle du cadre précédent etc)

                        Si tu n'utilises pas la pile implicite des appels de fonction, tu te retrouves à placer tes données et pointeurs de fonction dans un gros tableau que tu vides/remplis  explicitement : c'est une pile aussi...

                        La boucle de la ligne 42 me fait penser que tu es en train de réinventer le "threaded code".

                        https://www.complang.tuwien.ac.at/forth/threaded-code.html

                        -
                        Edité par michelbillaud il y a 5 minutes

                        En faite j'aurai certainement besoin d'une chaîne, car après le retour des "noeu" non terminaux, je doit savoir dans quel noeu revenir. La "pile" sera donc une chaîne alloué avec malloc et donc dans le tas et non dans la pile. De plus bravo pour ces article supplémentaire qui alimente la reflection.

                        PierrotLeFou a écrit:

                        As-tu une idée de la profondeur de tes récursivités?
                        J'imagine que les compilateurs actuels utilisent la récursivité.
                        Et même en Python, qui est un langage interprété, on peut aller par défaut jusqu'à un niveau de 1000 (+ ou - 2)

                        edit:

                        J'ai commis le programme stupide suivant:

                        #include <stdio.h>
                        int add(int n) {
                            if(n <= 0) return 0;
                            return n+add(n-1);
                        }
                        int main(void) {
                            int n;
                            scanf("%d", &n);
                            printf("%d\n", add(n));
                        }

                        Je me rend à plus de 43300 récursions sur Windows.

                        -
                        Edité par PierrotLeFou il y a environ 6 heures


                        Si c'est effective la cas alors oui peut être que je n’embête pour rien. Mai bon au moins il y auras une sécurité. Tu a essayé sur windows, peut être que dans l'embarqué par exemple ces différent?

                        PS: J'ai maintenant finie d'implémenté la chaîne avec les fonctions push et pop. Il me faut maintenant crée quelques noeux terminaux et non terminaux pour voir si tout fonctionne.



                        -
                        Edité par sdms 7 mai 2023 à 16:29:52

                        • Partager sur Facebook
                        • Partager sur Twitter
                          8 mai 2023 à 9:28:08

                          > J'ai maintenant finie d'implémenté la chaîne avec les fonctions push et pop.

                          push et pop, c'est les opérations caractéristiques sur une pile. Mais sur une chaîne ?

                          • Partager sur Facebook
                          • Partager sur Twitter
                            8 mai 2023 à 11:10:32

                            Oui j'utilise peut être le mauvais mot. J'ai donc maintenant finie d'implémenté la pile ( sur le tat :p)

                            Ok. Ont dirai que ça fonctionne. Mai je dois encore amélioré. Car je pense qu'il peut y avoir actuellement  des conflit quand un noeu prend en sortie deux noeu dans l'un est non terminaux

                            PS: J'ai corrigé, je pense que soit doit être bon. Mai avec ce type de code ont est pas à l’abri d'un bug.:euh:

                            -
                            Edité par sdms 8 mai 2023 à 16:27:18

                            • Partager sur Facebook
                            • Partager sur Twitter
                              9 mai 2023 à 13:14:23

                              Ok. On dirait que ça fonctionne. Mais je dois encore améliorer.

                              Car je pense qu'il peut y avoir actuellement  des conflits quand un noeud prend en sortie deux noeuds dont l'un est non terminal

                              • Partager sur Facebook
                              • Partager sur Twitter
                                9 mai 2023 à 13:28:50

                                >On dirait que ça fonctionne

                                C'est ce qu'on voit (pas), en tout cas on est contents de le savoir.

                                -
                                Edité par michelbillaud 9 mai 2023 à 13:29:06

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  9 mai 2023 à 17:29:41

                                  @Phil_1857: la langue maternelle de sdms n'est peut-être pas le français ? Et si tu veux corriger tous les commentaires de ce forum, c'est un travail à plus que plein temps.

                                  -
                                  Edité par edgarjacobs 9 mai 2023 à 17:30:06

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                    9 mai 2023 à 17:38:58

                                    edgarjacobs tu devrai aller dans la partie "français" du forum. mai je ne sais pas si elle existe :p

                                    Michelbillaud Je peut te montré le code mai il présente quelques défaut que je corrigerai pour mois même; mai ok je te le montre.

                                    le main:

                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    #include "pile.h"
                                    
                                    #define SizeTableau 200
                                    #define NonTermineau 1 /*** indique qu'il faut decrémenté l'indice de t de thing[t] ***/
                                    
                                    /*** Les fonction qui traite les différent Token ***/
                                    int noeuA(NextToken*, type, pile*);
                                    int noeuB(NextToken*, type, pile*);
                                    int noeuC(NextToken*, type, pile*);
                                    int noeuD(NextToken*, type, pile*);
                                    int noeuE(NextToken*, type, pile*);
                                    int noeuF(NextToken*, type, pile*);
                                    int noeuG(NextToken*, type, pile*);
                                    int noeuH(NextToken*, type, pile*);
                                    int noeuI(NextToken*, type, pile*);
                                    
                                    int main()
                                    {
                                        /*** liste des Token ***/
                                        type thing[SizeTableau]={Ident,Egual,Ident,Ident,Egual,Value,Plus,Value,OEF};
                                        pile *P=pile_new();
                                    
                                        NextToken Token;
                                        /*** Veryfie que le premiere Token est valide ***/
                                        if(thing[0]==Ident)
                                        Token.Next_token=noeuA;
                                        else
                                        return -1;
                                        Token.TokenType=thing[0];
                                        int t=0;
                                    
                                        /*** execute les fonctions voulue suivont les différents tokens ***/
                                        while(thing[t]!=OEF)
                                        {
                                            if(Token.Next_token(&Token,thing[t+1],P)==NonTermineau)
                                            {
                                                t--;
                                            }
                                            t++;
                                        }
                                        printf("fin de fichier");
                                        pile_free(P);
                                        return 0;
                                    }
                                    
                                    int noeuA(NextToken* NToken,type t,pile *p)
                                    {
                                        printf("Ident\n");
                                        if(t==Egual)
                                        NToken->Next_token=noeuB;
                                        else
                                        printf("erreur");
                                        return 0;
                                    
                                    }
                                    int noeuB(NextToken *NToken,type t,pile *p)
                                    {
                                        printf("Egual\n");
                                        if(t==Ident)
                                        NToken->Next_token=noeuC;
                                        else if(t==OEF)
                                        printf("erreur");
                                        else
                                        {
                                             NextToken Nt;
                                             Nt.Next_token=noeuA;
                                             NToken->Next_token=noeuE;
                                             pile_push(p,Nt,t);
                                        }
                                    
                                        return 0;
                                    }
                                    int noeuC(NextToken *NToken,type t,pile *p)
                                    {
                                        printf("Ident\n");
                                        if(t==Ident)
                                        NToken->Next_token=noeuA;
                                        else if(t!=OEF)
                                        printf("erreur");
                                        return 0;
                                    }
                                    int noeuD(NextToken *NToken,type t,pile *p)
                                    {
                                        //printf("Fin de fichier\n");
                                        return 0;
                                    }
                                    int noeuE(NextToken *NToken,type t,pile *p)
                                    {
                                        printf("Expression:=\n");
                                        if(t==OEF)
                                        printf("erreur");
                                        else
                                        {
                                             NToken->Next_token=noeuF;
                                        }
                                    
                                        return 0;
                                    }
                                    int noeuF(NextToken *NToken,type t,pile *p)
                                    {
                                        printf("Value\n");
                                        if(t==Value)
                                        NToken->Next_token=noeuG;
                                        else if(t==OEF)
                                        printf("erreur");
                                        return NonTermineau;
                                    }
                                    int noeuG(NextToken *NToken,type t,pile *p)
                                    {
                                        printf("Plus\n");
                                        if(t==Value)
                                        NToken->Next_token=noeuH;
                                        if(t==OEF)
                                        printf("erreur");
                                        return 0;
                                    }
                                    int noeuH(NextToken *NToken,type t,pile *p)
                                    {
                                        printf("Value\n");
                                        type tmp;
                                        if(t!=OEF)
                                        {
                                            NextToken Nt;
                                            pile_pop(p,&Nt,&tmp);
                                            NToken->Next_token=Nt.Next_token;
                                        }
                                        return 0;
                                    }
                                    int noeuI(NextToken *NToken,type t,pile *p)
                                    {
                                        if(t==Ident)
                                        NToken->Next_token=noeuA;
                                        else if(t!=OEF)
                                        printf("erreur");
                                        return 0;
                                    }
                                    

                                    pile.h

                                    #ifndef PILE_H_INCLUDED
                                    #define PILE_H_INCLUDED
                                    
                                    #include <stdio.h>
                                    #include <stdlib.h>
                                    
                                    /*** Token identité ***/
                                    typedef enum type{
                                        Ident,
                                        OEF,
                                        Virgule,
                                        Expression,
                                        Plus,
                                        Egual,
                                        LParent,
                                        RParent,
                                        LParagra,
                                        RParagra,
                                        Value
                                    }type;
                                    
                                    /*** structure pour pointé sur la fonction qui traite le prochain Token ***/
                                    typedef struct NextToken NextToken;
                                    typedef struct pile pile;
                                    
                                    typedef struct NextToken{
                                        int(*Next_token)(NextToken *NToken,type T,pile *p);
                                        type TokenType;
                                    }NextToken;
                                    
                                    typedef struct pileCell pileCell;
                                    typedef struct pileCell
                                    {
                                        pileCell *BottomCell;
                                        type TokenType;
                                        NextToken nextToken;
                                    }pileCell;
                                    
                                    /*** structure de pile pour retour de noeu non termineau ***/
                                    
                                    typedef struct pile
                                    {
                                        pileCell *TopCell;
                                    }pile;
                                    
                                    pile *pile_new();
                                    void pile_push(pile*,NextToken,type);
                                    void pile_pop(pile*,NextToken*,type*);
                                    void pile_free(pile*);
                                    
                                    #endif // PILE_H_INCLUDED
                                    

                                    pile.c

                                    #include "pile.h"
                                    
                                    pile *pile_new()
                                    {
                                         pile *p = malloc(sizeof(pile));
                                         p->TopCell=NULL;
                                         return p;
                                    }
                                    void pile_push(pile *p,NextToken Nt,type t)
                                    {
                                         pileCell *pc=malloc(sizeof(pileCell));
                                         if(p->TopCell!=NULL)
                                         {
                                            pc->BottomCell=p->TopCell;
                                         }
                                         p->TopCell=pc;
                                         pc->nextToken=Nt;
                                         pc->TokenType=t;
                                    }
                                    void pile_pop(pile *p,NextToken *Nt,type *t)
                                    {
                                         *Nt=p->TopCell->nextToken;
                                         *t=p->TopCell->TokenType;
                                         pileCell tmp;
                                         tmp.BottomCell=p->TopCell->BottomCell;
                                         free(p->TopCell);
                                         p->TopCell=tmp.BottomCell;
                                    }
                                    void pile_free(pile *p)
                                    {
                                        free(p);
                                    }
                                    

                                    Voila. Mai n'oublie pas que ce code n'est pas complet ! toute fois il fonctionne en démo et peut être exécuter en l'état.

                                    -
                                    Edité par sdms 9 mai 2023 à 18:00:32

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      13 mai 2023 à 11:25:48

                                      Ok. Pour ce que ça intéresse voila le schéma de principe de l'algorithme que je vais implémenté. A chaque fois que le noeux StLOOP et appeler il appelle lui même (par le pointeur de fonction) le noeux Statement 

                                      PS: voir le message suivant pour quelques informations utile.

                                      Grammaire du langage

                                      -
                                      Edité par sdms 5 juin 2023 à 16:35:43

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        5 juin 2023 à 16:33:15

                                        J'avais quelques bugs dans l’implémentation. Je vient  de les corriger. ça fonctionne bien.  Dans mon cas, à cause de la façon dans je gère la recherche ou non du prochain token, les nœud I,K et D retourne la valeur Nontermineau, malgré le fait qu'il son en fait des nœud terminaux. Cela permet de rester dans la boucle de retour pour continuer à exécuter les nœud non terminaux suivant sans repartir tout de suite sur la recherche du prochain token. Donc si quelqu'un souhaite utilisé cette façon de faire il devras pensé à ça.

                                        D'autre part Le nœud RetourD pointe en faite sur le nœud Début.

                                        -
                                        Edité par sdms 5 juin 2023 à 16:44:46

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Créer mon langage

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                        • Editeur
                                        • Markdown