1

Bon ce topic n'est la qu'a titre de curiosite personnel.. n'allez donc pas faire de conclusion attivewink
Je voulais juste savoir comment on faisait un compilateur de haut niveau?

Autre question: comment on fait un assemembleur... (ca rien a voir avec un compilo de haut niveau, mais je voudrai savoir comment on faitwink
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!

2

j'ai un cours de compilation cette annee.

-lexeur : source -> donnees plus evoluees. il existe des compilateurs de compilateurs : on entre la grammaire du langage et ca ressort un lexeur!

-verification des conditions de contexte : typage, tableaux, etc...

-production de code.

-optimisation globale du code

-optimisation locale du code.


Tout ca c'est grosso modo les grandes etapes mais il faut pas trop m'en demander, j'en saurai plus a la fin de l'annee
Je peux partir d'ici :
J'ai retrouvé mon nom !

Le Forum Ghibli

3

Je suppose que "lexeur" est une tentative de traduire le mot "parser", n'est-ce pas?
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

4

lexeur -> lexique ??

telchar > Au fait, vous êtes combien à l'ENS pour notre projet ?
Site : http://www.phareaway.com/
Membre du groupe Phare Away et webmaster du site

5

parseur si tu veux.
au passage il faut m'excuser s'il y a des erreurs, c'est le cours ou je suis le plus a la rue. wink


Miles> euuuuhhh..... moi tout seul ? grin
[edit]Edité par telchar le 09-12-2001 à 22:43:43[/edit]
Je peux partir d'ici :
J'ai retrouvé mon nom !

Le Forum Ghibli

6

Le lexeur réalise l'analyse lexicale : son rôle est de reconnaître dans le fichier source les mots-clé du langage, les identificateurs, les opérateurs.

Le parser c'est autre chose, son rôle est de construire des arbres de dérivation pour chaque expression, en se servant du travail du "lexeur", et par la même occasion si l'on veut, de vérifier les fautes de syntaxe.

Ensuite on peut oprimiser les arbres, puis générer le code ASM.

Pour illustrer, voici une toute petite partie du compilateur Azur : l'analyseur lexical. Il est assez spécial (le "préprocesseur" est imbriqué avec) :



TokensBin NextToken(char* Buffer, char SymGen)
{
  char *DebutP;
  register char Oper2;
  register int i;
  char CarSpecial;
  register Symbole *SymP;
  long *PtrT;
  
  
  NbTokensTotal++;
  *Buffer= 0;
  while (EstBlanc(*Curseur)) Curseur++;
  AncienCurseur= DebutP= Curseur;

  if (!*Curseur)
  {
    if (fichier == 0)
    {
      if (niveau != 0)
      {
        Erreur("fin de fichier dans une fonction")
        FermerCompilo();
      }
      NbTokensTotal--;
      return FIN;
    }
    HeapUnlock(ListeFichs[fichier--].handle);
    Curseur= ListeFichs[fichier].curseur;
    return NextToken(Buffer, SymGen);
  }

  if (EstSigne(*Curseur))
  {
    Oper2= Curseur[1];
    switch (*Curseur++)
    {
      case '?' : return INTERROGATION;
      case '[' : return CROCHETO;
      case ']' : return CROCHETF;
      case '(' : return PARENTO;
      case ')' : return PARENTF;
      case '{' : return ACCOLADEO;
      case '}' : return ACCOLADEF;
      case '@' : return AROBAS;
      case ',' : return VIRGULE;
      case ';' : return PNTVIRGULE;
      case '.' : if (Oper2 != '.')
                   return POINT;
                 else
                 {
                   if (*(++Curseur) == '.')
                   {
                     Curseur++;
                     return SUSPENSION;
                   }
                   else
                   {
                     Curseur--;
                     return POINT;
                   }
                 }
      case '$' : {
                   register char *ALNSO= ALNS;
                   
                   i= 0;
                   while (EstAlphaNumOPTIM(*Curseur))
                   {
                     *Buffer++= *Curseur++;
                     if (i++ == 31)
                     {
                       while (EstAlphaNumOPTIM(*Curseur)) Curseur++;
                       break;
                     }
                   }
                   *Buffer= 0;
                   Buffer-= i;
                   if (SymGen)
                   {
                     SymP= SymOffsetToPtr(NewSymbole());
                     PtrT= (long *)SymP->tailles;
                     *PtrT++= 0; *PtrT++= 0; *PtrT++= 0; *PtrT= 0;
                     sprintf(SymP->adresse, "#%lu", Base16toDeci(Buffer));
                     strcpy2(Buffer, LabelUnique(SymP->identif));
                     SymP->OffsetAdr= SymAdrOff1;
                     SymP->point= 0;
                     SymP->adressage= IMMEDIAT;
                     SymP->signe= FALSE;
                     SymP->readonly= TRUE;
                     SymP->adrmodif= TRUE;
                     SymP->PseudoPtr= FALSE;
                     SymP->unite= 0;
                     SymP->hierarchie= niveau;
                     SymP->UniteSiPtr= 0;
                     return IDENTIF;
                   } else
                   {
                     sprintf(Buffer, "%lu", Base16toDeci(Buffer));
                     return NOMBRE;
                   }
                 }
      case '%' : {
                   register char *ALNSO= ALNS;
                   
                   i= 0;
                   while (EstAlphaNumOPTIM(*Curseur))
                   {
                     *Buffer++= *Curseur++;
                     if (i++ == 31)
                     {
                       while (EstAlphaNumOPTIM(*Curseur)) Curseur++;
                       break;
                     }
                   }
                   *Buffer= 0;
                   Buffer-= i;
                   if (SymGen)
                   {
                     SymP= SymOffsetToPtr(NewSymbole());
                     PtrT= (long *)SymP->tailles;
                     *PtrT++= 0; *PtrT++= 0; *PtrT++= 0; *PtrT= 0;
                     sprintf(SymP->adresse, "#%lu", Base02toDeci(Buffer));
                     strcpy2(Buffer, LabelUnique(SymP->identif));
                     SymP->OffsetAdr= SymAdrOff1;
                     SymP->point= 0;
                     SymP->adressage= IMMEDIAT;
                     SymP->signe= FALSE;
                     SymP->readonly= TRUE;
                     SymP->adrmodif= TRUE;
                     SymP->PseudoPtr= FALSE;
                     SymP->unite= 0;
                     SymP->hierarchie= niveau;
                     SymP->UniteSiPtr= 0;
                     return IDENTIF;
                   } else
                   {
                     sprintf(Buffer, "%lu", Base02toDeci(Buffer));
                     return NOMBRE;
                   }
                 }
      case '~' : DebutP= Curseur;
                 if (SymGen)
                 {
                   char Adresse[33];
                   
                   if (NextToken(&Adresse[2], FALSE) == NOMBRE)
                   {
                     SymP= SymOffsetToPtr(NewSymbole());
                     PtrT= (long *)SymP->tailles;
                     *PtrT++= 0; *PtrT++= 0; *PtrT++= 0; *PtrT= 0;
                     strcpy2(Buffer, LabelUnique(SymP->identif));
                     SymP->OffsetAdr= SymAdrOff1;
                     SymP->point= 0;
                     SymP->adressage= IMMEDIAT;
                     SymP->readonly= TRUE;
                     SymP->adrmodif= TRUE;
                     SymP->PseudoPtr= FALSE;
                     SymP->unite= 0;
                     SymP->hierarchie= niveau;
                     SymP->UniteSiPtr= 0;
                     
                     if (Adresse[2] == '-')
                     {
                       Adresse[2]= '#';
                       strcpy2(SymP->adresse, &Adresse[2]);
                       SymP->signe= FALSE;
                     } else
                     {
                       Adresse[0]= '#';
                       Adresse[1]= '-';
                       strcpy2(SymP->adresse, Adresse);
                       SymP->signe= TRUE;
                     }
                     return IDENTIF;
                   } else
                   {
                     Curseur= DebutP;
                     return NEGATION;
                   }
                 } else
                 {
                   char Adresse[33];
                   
                   if (NextToken(&Adresse[1], FALSE) == NOMBRE)
                   {
                     Adresse[0]= '-';
                     if (Adresse[1] != '-') strcpy2(Buffer, Adresse);
                                       else strcpy2(Buffer, &Adresse[2]);
                     return NOMBRE;
                   } else
                   {
                     Curseur= DebutP;
                     return NEGATION;
                   }
                 }
      case ''': if (Oper2 != ''' && *(Curseur+1) != ''')
                 {
                   Erreur("trop grand pour une constante caractère")
                   while (*Curseur != ''' && *Curseur) Curseur++;
                   if (*Curseur) Curseur++;
                   return ERREUR;
                 }
                 SymP= SymOffsetToPtr(NewSymbole());
                 if (Oper2 == ''' && *(Curseur+1) != ''')
                 {
                   SymP->adresse[0]= '#';
                   SymP->adresse[1]= '0';
                   SymP->adresse[2]= 0;
                   Curseur++;
                 } else
                 {
                   sprintf(SymP->adresse, "#%u", (unsigned int)Oper2);
                   Curseur+= 2;
                 }
                 if (SymGen)
                 {
                   PtrT= (long *)SymP->tailles;
                   *PtrT++= 0; *PtrT++= 0; *PtrT++= 0; *PtrT= 0;
                   strcpy2(Buffer, LabelUnique(SymP->identif));
                   SymP->OffsetAdr= SymAdrOff1;
                   SymP->point= 0;
                   SymP->adressage= IMMEDIAT;
                   SymP->signe= FALSE;
                   SymP->readonly= TRUE;
                   SymP->adrmodif= TRUE;
                   SymP->PseudoPtr= FALSE;
                   SymP->unite= 0;
                   SymP->hierarchie= niveau;
                   SymP->UniteSiPtr= 0;
                   return IDENTIF;
                 } else
                 {
                   strcpy2(Buffer, SymP->adresse + 1);
                   NbSymboles--;
                   return NOMBRE;
                 }
      case '"': Oper2= *(Curseur-1);
                 while ((*Curseur!='"' || Oper2=='\') && *Curseur)
                   Oper2= *Curseur++;
                 if (!*Curseur)
                 {
                   Erreur("chaîne sans fin")
                   return ERREUR;
                 }
                 Curseur++;
                 if (SymGen)
                 {
                   if (IndexGlobal % 2)
                   {
                     IndexGlobal++;
                     if (CommenterCodeASM) fprintf(Vars, " dc.b 0 ;evenn")
                                      else fprintf(Vars, " dc.b 0n")
                   }
                   fprintf(Vars, " dc.b ")
                   i= -1;
                   while (DebutP != Curseur)
                   {
                     if ((Oper2= *DebutP++) != 13 && Oper2 != '\') fputc(Oper2, Vars);
                     else
                     {
                       if (Oper2 == 13)
                       {
                         CarSpecial= 'n';
                         DebutP++;
                       } else
                         switch (*DebutP++)
                         {
                           case '0' : ;
                           case '1' : ;
                           case '2' : ;
                           case '3' : ;
                           case '4' : ;
                           case '5' : ;
                           case '6' : ;
                           case '7' : ;
                           case '8' : ;
                           case '9' : CarSpecial= *(DebutP-1) - '0';
                                      if (EstNumerique(*DebutP))
                                      {
                                        CarSpecial*= 10;
                                        CarSpecial+= (*DebutP++) - '0';
                                        if (EstNumerique(*DebutP))
                                        {
                                          CarSpecial*= 10;
                                          CarSpecial+= (*DebutP++) - '0';
                                        }
                                      }
                                      break;
                           case '\': CarSpecial= '\'; break;
                           case 'n' : CarSpecial= 'n'; break;
                           case '"': CarSpecial= '"'; break;
                           case ''': CarSpecial= '''; break;
                           default  : Erreur("séquence d'échappement inconnue")
                                      return ERREUR;
                         } // fin switch (Oper2)
                       fprintf(Vars, "",%u,"", CarSpecial & 0xFF);
                     } // fin else de if ((Oper2= *DebutP++) != 13 && Oper2 != '\')
                     i++;
                   } // fin while (DebutP != Curseur)
                   fprintf(Vars, ",0n")
                   
                   SymP= SymOffsetToPtr(NewSymbole());
                   sprintf(SymP->adresse, "%u(a5)", IndexGlobal);
                   PtrT= (long *)SymP->tailles;
                   *PtrT++= 0; *PtrT++= 0; *PtrT++= 0; *PtrT= 0;
                   strcpy2(Buffer, LabelUnique(SymP->identif));
                   SymP->OffsetAdr= SymAdrOff1;
                   SymP->tailles[0]= i;
                   SymP->point= 0;
                   SymP->adressage= DEPLACE;
                   SymP->signe= FALSE;
                   SymP->readonly= TRUE;
                   SymP->adrmodif= TRUE;
                   SymP->PseudoPtr= TRUE;
                   SymP->TabOuFonc= 0;
                   SymP->unite= 1;
                   SymP->hierarchie= niveau;
                   SymP->UniteSiPtr= 1;
                   
                   IndexGlobal+= i;
                   return IDENTIF;
                 } else // faux if (SymGen)
                 {
                   i= 0;
                   DebutP++;
                   while (DebutP != Curseur)
                   {
                     *(Buffer++)= *DebutP++;
                     if (i++ == 32) break;
                   }
                   *(--Buffer)= 0;
                   return CHAINE;
                 }
      case ':' : NbTokensTotal--;
                 if (Oper2 == ':')
                 {
                   Curseur++;
                   while (*Curseur++ != ':' || *Curseur != ':');
                   Curseur++;
                   return NextToken(Buffer, SymGen);
                 } else
                 {
                   SynchroRC();
                   return NextToken(Buffer, SymGen);
                 }
                 break;
      case '#' : if (!NextToken(Buffer, FALSE))
                 {
                   SynchroRC();
                   return NextToken(Buffer, SymGen);
                 }
                 switch (Buffer[0])
                 {
                   case 'i' : if (!strcmp2(Buffer, "include"))
                              {
                                if (fichier == 31)
                                {
                                  Erreur("limite de 32 imbrications de fichiers atteinte")
                                  FermerCompilo();
                                }
                                if (!NextToken(Buffer, FALSE))
                                {
                                  SynchroRC();
                                  return NextToken(Buffer, SymGen);
                                }
                                ListeFichs[fichier].curseur= Curseur;
                                fichier++;
                                Buffer[17]= 0;
                                if (!strchr2(Buffer, '\'))
                                {
                                  sprintf(ListeFichs[fichier].nom, "%s%s", RepSrc, Buffer);
                                  if (!CompleterSource(&ListeFichs[fichier]))
                                  {
                                    sprintf(ListeFichs[fichier].nom, "azur\%s", Buffer);
                                    if (!CompleterSource(&ListeFichs[fichier]))
                                    {
                                      fichier--;
                                      Erreur("le fichier indiqué n'existe pas")
                                      return NextToken(Buffer, SymGen);
                                    }
                                  }
                                  HeapLock(ListeFichs[fichier].handle);
                                  Curseur= ListeFichs[fichier].curseur;
                                  return NextToken(Buffer, SymGen);
                                }
                                strcpy2(ListeFichs[fichier].nom, Buffer);
                                if (!CompleterSource(&ListeFichs[fichier]))
                                {
                                  fichier--;
                                  Erreur("le fichier indiqué n'existe pas")
                                  return NextToken(Buffer, SymGen);
                                }
                                HeapLock(ListeFichs[fichier].handle);
                                Curseur= ListeFichs[fichier].curseur;
                                return NextToken(Buffer, SymGen);
                              }
                              break;
                   case 'r' : if (!strcmp2(Buffer, "redecon"))
                              {
                                TesterRedeclarations= TRUE;
                                return NextToken(Buffer, SymGen);
                              } else
                              if (!strcmp2(Buffer, "redecoff"))
                              {
                                TesterRedeclarations= FALSE;
                                return NextToken(Buffer, SymGen);
                              }
                              break;
                   case 'c' : if (!strcmp2(Buffer, "common"))
                              {
                                CommenterCodeASM= TRUE;
                                return NextToken(Buffer, SymGen);
                              } else
                              if (!strcmp2(Buffer, "commoff"))
                              {
                                CommenterCodeASM= FALSE;
                                return NextToken(Buffer, SymGen);
                              }
                              break;
                   case 'f' : if (!strcmp2(Buffer, "falselabels"))
                              {
                                ImposerLabels= TRUE;
                                return NextToken(Buffer, SymGen);
                              }
                              break;
                   case 't' : if (!strcmp2(Buffer, "truelabels"))
                              {
                                ImposerLabels= FALSE;
                                return NextToken(Buffer, SymGen);
                              }
                              break;
                 }
                 Erreur("directive de compilation inconnue")
                 SynchroRC();
                 return NextToken(Buffer, SymGen);
      case '!' : if      (Oper2 == '=') {Curseur++; return DIFFERENT;}
                 else if (Oper2 == '!') {Curseur++; return EXCLAM2;}
                 else                   {return EXCLAM;}
      case '*' : if      (Oper2 != '=') {return MULTIPL;}
                 else                   {Curseur++; return MULTEGAL;}
      case '/' : if      (Oper2 != '=') {return DIVISE;}
                 else                   {Curseur++; return DIVISEGAL;}
      case '\': if      (Oper2 != '=') {return MODULO;}
                 else                   {Curseur++; return MODULOEGAL;}
      case '+' : if      (Oper2 == '+') {Curseur++; return PLUSPLUS;}
                 else if (Oper2 != '=') {return PLUS;}
                 else                   {Curseur++; return PLUSEGAL;}
      case '-' : if      (Oper2 == '-') {Curseur++; return MOINSMOINS;}
                 else if (Oper2 != '=') {return MOINS;}
                 else                   {Curseur++; return MOINSEGAL;}
      case '=' : if      (Oper2 != '=') {return EGAL;}
                 else                   {Curseur++; return EGALC;}
      case '&' : if      (Oper2 == '&') {Curseur++; return ANDC;}
                 else if (Oper2 == '=') {Curseur++; return ANDEGAL;}
                 else                   {return AND;}
      case '^' : if      (Oper2 == '=') {Curseur++; return XOREGAL;}
                 else                   {return XOR;}
      case '|' : if      (Oper2 == '|') {Curseur++; return ORC;}
                 else if (Oper2 == '=') {Curseur++; return OREGAL;}
                 else                   {return OR;}
      case '<' : if      (Oper2 == '<')
                 {
                   if (*(++Curseur) != '=')
                     {return DECALG;}
                   else
                     {Curseur++; return DECALGEGAL;}
                 }
                 else if (Oper2 == '=') {Curseur++; return INFEREG;}
                 else if (Oper2 != '>') {return INFERIEUR;}
                 else                   {Curseur++; return PERMUTATION;}
      case '>' : if      (Oper2 == '>')
                 {
                   if (*(++Curseur) != '=')
                     {return DECALD;}
                   else
                     {Curseur++; return DECALDEGAL;}
                 }
                 else if (Oper2 == '=') {Curseur++; return SUPEREG;}
                 else                   {return SUPERIEUR;}
      default  : Erreur("opérateur inexistant en Azur")
                 return ERREUR;
    } // fin switch (*Curseur++)
  } // faux if EstSigne(*Curseur)
  else if (EstAlphabetique(*Curseur)) // Identificateurs & mots réservés
  {
    register char *ALNSO= ALNS;
    
    i= 0;
    while (EstAlphaNumOPTIM(*Curseur))
    {
      *Buffer++= *Curseur++;
      if (i++ == 30)
      {
        while (EstAlphaNumOPTIM(*Curseur)) Curseur++;
        break;
      }
    }
    *Buffer= 0;
    Buffer-= i;
    
    switch (*Buffer++)
    {
      case 'b' : if      (!strcmp2(Buffer, "yte"))     return BYTE;
                 else if (!strcmp2(Buffer, "reak"))    return BREAK;
                 return IDENTIF;
      case 'c' : if      (!strcmp2(Buffer, "ontinue")) return CONTINUE;
                 return IDENTIF;
      case 'd' : if      (!strcmp2(Buffer, "o"))       return DO;
                 return IDENTIF;
      case 'e' : if      (!strcmp2(Buffer, "lse"))     return ELSE;
                 else if (!strcmp2(Buffer, "xtern"))   return EXTERN;
                 return IDENTIF;
      case 'f' : if      (!strcmp2(Buffer, "or"))      return FOR;
                 return IDENTIF;
      case 'g' : if      (!strcmp2(Buffer, "oto"))     return GOTO;
                 return IDENTIF;
      case 'i' : if      (!strcmp2(Buffer, "f"))       return IF;
                 return IDENTIF;
      case 'l' : if      (!strcmp2(Buffer, "ong"))     return LONG;
                 return IDENTIF;
      case 'r' : if      (!strcmp2(Buffer, "eturn"))   return RETURN;
                 return IDENTIF;
      case 's' : if      (!strcmp2(Buffer, "tep"))     return STEP;
                 return IDENTIF;
      case 't' : if      (!strcmp2(Buffer, "hen"))     return THEN;
                 else if (!strcmp2(Buffer, "o"))       return TO;
                 return IDENTIF;
      case 'v' : if      (!strcmp2(Buffer, "oid"))     return VOID;
                 return IDENTIF;
      case 'w' : if      (!strcmp2(Buffer, "ord"))     return WORD;
                 else if (!strcmp2(Buffer, "hile"))    return WHILE;
                 return IDENTIF;
    } // fin switch (*Buffer++)
    return IDENTIF;
  } // faux if (EstAlphabetique(*Curseur))
  else if (EstNumerique(*Curseur))
  {
    SymP= SymOffsetToPtr(NewSymbole());
    
    DebutP= SymP->adresse;
    *DebutP++= '#';
    i= 0;
    while (EstNumerique(*Curseur))
    {
      *DebutP++= *Curseur++;
      if (i++ == 9)
      {
        while (EstAlphaNum(*Curseur)) Curseur++;
        break;
      }
    }
    *DebutP= 0;
    if (EstAlphabetique(*Curseur))
    {
      Erreur("format numérique incorrect")
      while (EstAlphaNum(*Curseur)) Curseur++;
      return ERREUR;
    }
    
    if (SymGen)
    {
      PtrT= (long *)SymP->tailles;
      *PtrT++= 0; *PtrT++= 0; *PtrT++= 0; *PtrT= 0;
      strcpy2(Buffer, LabelUnique(SymP->identif));
      SymP->OffsetAdr= SymAdrOff1;
      SymP->point= 0;
      SymP->adressage= IMMEDIAT;
      SymP->signe= FALSE;
      SymP->readonly= TRUE;
      SymP->adrmodif= TRUE;
      SymP->PseudoPtr= FALSE;
      SymP->unite= 0;
      SymP->hierarchie= niveau;
      SymP->UniteSiPtr= 0;
      return IDENTIF;
    } else
    {
      strcpy2(Buffer, &SymP->adresse[1]);
      NbSymboles--;
      return NOMBRE;
    }
  }
  else
  {
    Curseur++;
    Erreur("caractère inconnu du compilateur")
    return ERREUR;
  }
}

[edit]Edité par Thibaut le 10-12-2001 à 11:51:59[/edit]
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

7

lexer, parseur... je suis vraiment a la rue sad
Je peux partir d'ici :
J'ai retrouvé mon nom !

Le Forum Ghibli

8

Ca reste des details.

9

... c'est quand même à la base des compilateurs !
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.