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

Générateurs de compilateur Discussion :

Problème de compréhension d'un 'detail' dans la doc de Bison.


Sujet :

Générateurs de compilateur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Par défaut Problème de compréhension d'un 'detail' dans la doc de Bison.
    Bonjour !
    Je lis petit à petit la doc de Bison et en suis au dernier exemple...
    Je copie/colle 'seulement' les declarations Bisons, la definition du type YYSTYPE généré par Bison, la définition du type symrec et une partie du code correspondant au lexer :

    %{Prologue%} et déclarations Bison :
    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
     
    %{
      #include <stdio.h>  /* For printf, etc. */
      #include <math.h>   /* For pow, used in the grammar.  */
      #include "calc.h"   /* Contains definition of 'symrec'.  */
      int yylex (void);
      void yyerror (char const *);
    %}
    %define api.value.type union /* Generate YYSTYPE from these types:  */
    %token <double>  NUM         /* Simple double precision number.  */
    %token <symrec*> VAR FNCT    /* Symbol table pointer: variable and function.  */
    %type  <double>  exp
     
    %precedence '='
    %left '-' '+'
    %left '*' '/'
    %precedence NEG /* negation--unary minus */
    %right '^'      /* exponentiation */
    Ces declarations Bison générent (entre autres) le type YYSTYPE défini par :
    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
     
    typedef union YYSTYPE YYSTYPE;
    union YYSTYPE
    {
     
    #line 140 "gram.tab.c" /* yacc.c:355  */
      /* NUM  */
      double NUM;
      /* exp  */
      double exp;
      /* VAR  */
      symrec* VAR;
      /* FNCT  */
      symrec* FNCT;
    };

    Définition du type symrec :
    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
     
    /* Function type.  */
    typedef double (*func_t) (double);
    /* Data type for links in the chain of symbols.  */
    struct symrec
    {
      char *name;  /* name of symbol */
      int type;    /* type of symbol: either VAR or FNCT */
      union
      {
        double var;      /* value of a VAR */
        func_t fnctptr;  /* value of a FNCT */
      } value;
      struct symrec *next;  /* link field */
    };
    typedef struct symrec symrec;
    Enfin le code du lexer que j'ai raccourci pour me concentrer sur mon problème qui a lieu pile à la ligne 43 :
    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
    44
    45
    int
    yylex (void)
    {
      int c;
    /***************************************************
    * du code qui peut être résumé par un simple 
    c=getchar();
    *pour la suite
    ***************************************************/ 
      /* Char starts an identifier => read the name.       */
      if (isalpha (c))
        {
          /* Initially make the buffer long enough
             for a 40-character symbol name.  */
          static size_t length = 40;
          static char *symbuf = 0;
          symrec *s;
          int i;
          if (!symbuf)
            symbuf = (char *) malloc (length + 1);
     
          i = 0;
          do
            {
              /* If buffer is full, make it bigger.        */
              if (i == length)
                {
                  length *= 2;
                  symbuf = (char *) realloc (symbuf, length + 1);
                }
              /* Add this character to the buffer.         */
              symbuf[i++] = c;
              /* Get another character.                    */
              c = getchar ();
            }
          while (isalnum (c));
     
          ungetc (c, stdin);
          symbuf[i] = '\0';
          s = getsym (symbuf);
          if (s == 0)
            s = putsym (symbuf, VAR);
          *((symrec**) &yylval) = s; /*<<<<<<< J'AI LONGTEMPS BUGGE LA ! */
          return s->type;
        }
    Tout d'abord :
    1) Quand j'ai lu le code j'ai cru a une erreur et non pas du tout ca compile et fonctionne parfaitement.
    2) J'ai remplacé ce 'fatras' par :
    et ca marche encore et c'est (je crois) ce que fait cette fameuse ligne 43...
    3) Ayant réféchi je comprends maintenant cette ligne 43 mais j'ai des questions du coup :

    Q1. Est ce que je me trompe en pensant que ma façon d'écrire est plus claire ?
    Q2. Y a t il un intérêt à écrire cette ligne 43 de cette manière dans ce cas précis ?
    (J'ai vu un intérêt plus loin dans la doc dans le cas ou le token n'est pas explicitement nommé...)
    Q3. Pour vous, codeurs expérimentés que vous êtes... ca vous vient naturellement ce genre de formulation bizarroïdes ?

    Voila, c'est tout et c'est déjà pas mal !
    Merci aux courageux qui ont lu jusqu'ici...

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Par défaut
    Je reviens avec une version plus synthétique de ma question....
    En fait inutile de lire tout le code que j'ai mis là haut pour la comprendre.
    Imaginez que vous ayez un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef union S { int entier; char* pchar; } S;
    Vous viendrait il à l'idée d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    S inst;
    void f(char* npchar)
    {
    *((char**) &inst) = npchar;
    }
    Plutot que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    S inst;
    void f(char* npchar)
    {
    inst.pchar = npchar;
    }
    Le second m'a l'air plus facilement lisible... par contre quand je vois que les gens à qui l'ont fait confiance pour écrire la doc de Bison écrivent plutôt la première version, je me dis qu'il y a peut être quelque chose de plus à y comprendre.
    Votre avis ?

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Ton code m'a l'air en effet plus clair et équivalent.
    D'un autre côté, j'ai du mal à voir pourquoi le lexer n'utilise pas simplement flex...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    C'est probablement de l'héritage du temps où ca n'aurait pas été une union.

    Auquel cas, il s'agit d'un viol du système de type pour pouvoir écrire arbitrairement à l'emplacement de cette variable.
    En pratique, c'est à proscrire autant que possible.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Par défaut
    Dans la suite de la doc, on voit que cette façon étrange d'accéder au contenu de l'union devient une obligation lorsqu on ne donne pas de nom au token (qui pourrait être juste '+') et que l'on veut malgré tout y associer un type sémantique.

    @Medinoc :
    Je lis la documentation Bison et ils y etudient des exemples relativement simples et surtout 'auto contenus'. Dans la pratique et dans un cas plus complexe, j'imagine qu'on ferait effectivement appel a flex pour écrire le lexer...

    Merci pour vos réponses en tout cas, elles me confortent sur mon niveau de compréhension.

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

Discussions similaires

  1. Problème d'affichage d'une variable dans un doc Word
    Par d.martin77 dans le forum VBA Word
    Réponses: 0
    Dernier message: 11/06/2014, 21h55
  2. Réponses: 9
    Dernier message: 24/09/2011, 17h07
  3. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07
  4. problème xsl : inclure une donnée xml dans une balise html
    Par djodjo dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 03/01/2003, 09h24
  5. [langage] Problème de taille de fichier à mettre dans
    Par And_the_problem_is dans le forum Langage
    Réponses: 10
    Dernier message: 13/08/2002, 09h41

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