Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1979 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Probleme d'analyse lexicale

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Probleme d'analyse lexicale

n°992923
Chronoklaz​m
Posté le 24-02-2005 à 21:10:17  profilanswer
 

Voila j'ai deux petits problemes avec mon lexer (pas de flex) pour le petit langage Logo.  
 
La reconnaissance des operateurs '<< ' se fait correctement mais dès que il y a un nombre (ou autre à part un espace) tout de suite apres ... ça gouille.
exemple :  
'<<20' donnera 'operateur nombre' au lieu de 'operateur operateur nombre'
alors que
'<<' donne bien 'operateur operateur'  :fou:  
 
Et ma deuxième question concerne la gestion des identificateurs (qui sont à priori gerés dans le meme état que les mot-cle et le sens), en fait il faut pouvoir reconnaitre le lexeme le plus long (par convention) donc par exemple le motcle "avancer" devra etre reconnu au lieu d'une suite d'identificateurs "a","v","a","n"...
Je pense qu'il faut d'abord que je teste la correspondance avec un motcle puis si elle echoue tester la reconnaisance d'un id.
 
 
Voici le source :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. /* Macros pour les mots clef */
  6. #define IDENTIFICATEUR 1
  7. #define MOTCLE 2
  8. #define SENS 3
  9. #define OPERATEUR 4
  10. #define ANGLE 5
  11. #define NOMBRE 6
  12. #define FIN 7
  13. #define ERROR 0
  14. /* La fonction getkar */
  15. int getkar(FILE* fp){
  16.   int x = fgetc(fp);
  17.   if((x == '\n') || (x == '\r')) printf("\n" );
  18.   if(isspace(x))
  19.     printf("" );
  20.   else
  21.     printf("\n :- %c\n ", x); //afficher le lexeme lus
  22.   return x;
  23.    
  24. }
  25. /* La fonction lexer */
  26. int lexer(FILE* fp){
  27.   int s, z, i = 0; /* z est le carac lus et i indice du buffer */
  28.   char etat = 'a';
  29.   short exception1=0; /* Variable pour gerer l'exception du lexeme ANGLE */
  30.   char buf[50]="";
  31.   char temp;
  32.  
  33.   while(s<= 12){
  34.     printf("Etat => %c", etat);
  35.        
  36.     if(feof(fp) || z==EOF) return FIN;
  37.     s++;
  38.     z=getkar(fp);
  39.     if(isspace(z)){
  40.        i=0;
  41.        //continue;
  42.     }
  43.     if(isalpha(z)){ etat='h';}
  44.     if(z =='.') etat='d';
  45.     if(z =='<') { etat='e';}
  46.     if(z =='>') { etat='g';}
  47.     if(z == ':') { etat = 'i';}
  48.     if(strchr("+-*/(){}", z)) { etat = 'f'; }
  49.     if(isdigit(z) || exception1==1) {exception1=0; etat='b'; }
  50.     /* Pour le caractere '=' on definit l'etat selon le caractere temporisé precedement */
  51. if(z == '=')
  52. {
  53.  if (temp==':') etat='i';
  54.  else if (temp=='<') etat='e';
  55.  else if (temp=='>') etat='g';
  56.  else etat = 'f';
  57. }
  58.     /* A PARTIR D'ICI ON A LA GESTION DES ETATS */
  59.    
  60.     /* Si on se trouve dans cet etat c'est que on a deja lu un nombre.
  61.    Donc si on lit autre chose qu'un nombre (à part g ou d ou r)  
  62.    alors on renvoi un nombre etc ... */
  63. if(etat=='b'){
  64.        if(isdigit(z)){
  65.   exception1=1;
  66.   continue;
  67.  }
  68.  else{
  69.   if(strchr("gdr",z)) return ANGLE;
  70.      else return NOMBRE;
  71.  }
  72. }
  73.     /* Etat pour detecter les motcle, id et sens */
  74.     if (etat=='h'){
  75.       if (isalnum(z)){
  76.  buf[i]=z;
  77.         i++;
  78.  //printf(" buffer : %s\n", buf);
  79.  if ((strcmp(buf, "avancer" ) == 0)  ||
  80.   (strcmp(buf, "lever" ) == 0)    ||
  81.   (strcmp(buf, "poser" ) == 0)    ||
  82.   (strcmp(buf, "tourner" ) == 0)  ||
  83.                         (strcmp(buf, "pour" )  == 0)    ||
  84.                  (strcmp(buf, "sinon" ) == 0)    ||
  85.          (strcmp(buf, "tantque" ) == 0)  ||
  86.                         (strcmp(buf, "si" ) == 0))
  87.  {
  88.   
  89.    //printf(" buffer : %s\n", buf);
  90.    return MOTCLE;
  91.  }
  92.  
  93.     else if ((strcmp(buf,"gauche" )==0) || (strcmp(buf, "droite" ) == 0)) return SENS;
  94.     else continue;
  95.   }
  96.   else{
  97.    ungetc(z, fp);
  98.    continue
  99.   }
  100.     
  101.     }
  102. /* - Gestion de l'operateur '<' et '<=' */
  103. if (etat=='e'){
  104.  if(!isspace(z)){
  105.   if(z=='=' && temp=='<') return OPERATEUR;
  106.   else if(z!='=' && temp=='<') {ungetc(z, fp); return OPERATEUR;}
  107.   else {temp='<'; continue;}
  108.   }
  109.   else{
  110.   if(temp=='<') return OPERATEUR;
  111.   else continue;
  112.  }
  113.  }
  114. /* - Gestion de l'operateur '>' et '>=' */
  115.         if (etat=='g'){
  116.  if(!isspace(z)){
  117.   if(z=='=' && temp=='>') return OPERATEUR;
  118.   else if(z!='=' && temp=='>') {ungetc(z, fp); return OPERATEUR;}
  119.   else {temp='>'; continue;}
  120.   }
  121.   else{
  122.   if(temp=='>') return OPERATEUR;
  123.   else continue;
  124.  }
  125.  }   
  126.     /* Gestion de l'operateur ':=' */
  127.     if (etat=='i'){
  128.  if(!isspace(z)){
  129.   if(z=='=' && temp==':') return OPERATEUR;
  130.   else if(z!='=' && temp==':') {ungetc(z, fp); return ERROR;}
  131.   else {temp=':'; continue;}
  132.   }
  133.   else{
  134.   if(temp==':') return ERROR;
  135.   else continue;
  136.  }
  137.  }
  138.     /* Gestion de l'operateur '.' et '..' */
  139.     if (etat=='d'){
  140. if(!isspace(z)){
  141.  if(z=='.' && temp=='.') return OPERATEUR;
  142.  else if(z!='.' && temp=='.') {ungetc(z, fp); return ERROR;}
  143.  else {temp='.'; continue;}
  144.   }
  145.   else{
  146.  if(temp=='.') return ERROR;
  147.  else continue;
  148.  }
  149. }
  150.    
  151.     if (etat=='f') return OPERATEUR;
  152.    
  153.   }
  154.   return FIN;
  155. }
  156. int main(int argc, char *argv[]){
  157.   FILE* fp = fopen("source.txt", "r" );
  158.  
  159.   int x=0;
  160.   while(x!=FIN){
  161.    
  162.     x = lexer(fp);
  163.     printf(" " );
  164.     if (x==ERROR) printf("Erreur! " );
  165.     switch (x)
  166.       {
  167.       case IDENTIFICATEUR:
  168.       printf("ident " );
  169.       break;
  170.       case MOTCLE :
  171.       printf("mot-cle " );
  172.       break;
  173.       case SENS :
  174.       printf("sens " );
  175.       break;
  176.       case OPERATEUR :
  177.    printf("operateur " );
  178.    break;
  179.   case NOMBRE :
  180.      printf("nombre " );
  181.    break;
  182.       case ANGLE :
  183.    printf("angle " );
  184.    break;
  185.      
  186.       }
  187.   }
  188.   exit(0);
  189. }


Message édité par Chronoklazm le 24-02-2005 à 21:40:45

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
mood
Publicité
Posté le 24-02-2005 à 21:10:17  profilanswer
 

n°992942
chrisbk
-
Posté le 24-02-2005 à 21:19:25  profilanswer
 

mais pkoi pas de flex/yacc ? [:sisicaivrai]

n°992950
Chronoklaz​m
Posté le 24-02-2005 à 21:35:45  profilanswer
 

C'est surement pour que les neuneus come moi puissent éprouver un profond plaisir en utilisant flex/yacc :sweat:


Message édité par Chronoklazm le 24-02-2005 à 21:36:22

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°992956
chrisbk
-
Posté le 24-02-2005 à 21:42:16  profilanswer
 

serieux, tu te fais du mal, la

n°992969
Chronoklaz​m
Posté le 24-02-2005 à 21:54:58  profilanswer
 

Et encore on a pas attaquer les generateurs d'analyseurs syntaxiques à faire à la main.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°992971
chrisbk
-
Posté le 24-02-2005 à 21:55:21  profilanswer
 

mais mayrde quoi [:sisicaivrai]

n°992983
Chronoklaz​m
Posté le 24-02-2005 à 22:05:59  profilanswer
 

chrisbk a écrit :

mais mayrde quoi [:sisicaivrai]


 
Bon, je te sens chaud pour m'aider là, non ? :)


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°993008
Sve@r
Posté le 24-02-2005 à 22:22:48  profilanswer
 

Chronoklazm a écrit :

Voila j'ai deux petits problemes avec mon lexer (pas de flex) pour le petit langage Logo.  
 
La reconnaissance des operateurs '<< ' se fait correctement mais dès que il y a un nombre (ou autre à part un espace) tout de suite apres ... ça gouille.
exemple :  
'<<20' donnera 'operateur nombre' au lieu de 'operateur operateur nombre'
alors que
'<<' donne bien 'operateur operateur'  :fou:  
 
Et ma deuxième question concerne la gestion des identificateurs (qui sont à priori gerés dans le meme état que les mot-cle et le sens), en fait il faut pouvoir reconnaitre le lexeme le plus long (par convention) donc par exemple le motcle "avancer" devra etre reconnu au lieu d'une suite d'identificateurs "a","v","a","n"...
Je pense qu'il faut d'abord que je teste la correspondance avec un motcle puis si elle echoue tester la reconnaisance d'un id.


 
Pfffou... tout ça à débugguer je suis fatigué d'avance.
Juste pour dire que ta seconde hypothèse estvraie. Tu dois reconnaître le lexème (token) le plus long possible à chaque fois.

n°993014
pains-aux-​raisins
Fatal error
Posté le 24-02-2005 à 22:27:07  profilanswer
 

Chrono> chai pas si c moi qui ait la berlu mais ton programme comporte des erreurs de programmation assez grossières. Par exemple lorsque les variables s ou temp sont utilisées pour la première fois, ces dernières ne sont pas initialisées ou définies.
Ensuite sur la forme, ce qu'on peut remarquer à première vue, c'est que la forme canonique pour écrire un AFN en langage C, utilise le switch...case pour la gestion des états, ce qui évite les continue à tout bout de champ.
Voilà pour mes premières remarques.
 
Bonne chance... ;)

n°993037
Chronoklaz​m
Posté le 24-02-2005 à 22:47:31  profilanswer
 

Ok merci, pour le switch.  
La variable s est initialisée a 0.
La variable temp, est comme son nom l'indique sert de mini-buffer donc bon ... mais je vais l'initialiser quand meme.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
mood
Publicité
Posté le 24-02-2005 à 22:47:31  profilanswer
 

n°993074
Chronoklaz​m
Posté le 24-02-2005 à 23:03:00  profilanswer
 

pains-aux-raisins a écrit :

Chrono> ... la forme canonique pour écrire un AFN en langage C, utilise le switch...case pour la gestion des états ...


 
Heu, t'as pas un exemple par hasard, google n'est pas tres bavard a ce sujet. :whistle:


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°993078
pains-aux-​raisins
Fatal error
Posté le 24-02-2005 à 23:06:18  profilanswer
 

ben tout simplement

Code :
  1. switch (etat) {
  2.    case ETAT1 :
  3.       ...
  4.       break;
  5.    case ETAT2 :
  6.       ...
  7.       break;
  8.    ...
  9.    case ETATn :
  10.       ...
  11.       break;
  12.    default :
  13.       /* là c'est pas normal ! */
  14. }

n°993093
Chronoklaz​m
Posté le 24-02-2005 à 23:18:14  profilanswer
 

Oui ok ca j'avais compris :D je parlais plus d'exemples de codages d'automates faits entierement.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°993097
Chronoklaz​m
Posté le 24-02-2005 à 23:21:55  profilanswer
 

J'ai trouvé un petit exemple sympa sur un AFN qui vire les espaces en debut de lignes mais c'est un peu leger ...
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int
  4. main()
  5. {
  6.     int c;
  7.     enum {ETAT_DBT_LIGNE, ETAT_NORMAL } etat = ETAT_DBT_LIGNE;
  8.  
  9.     while ((c=getchar()) != EOF) {
  10.         switch (etat) {
  11.             case ETAT_DBT_LIGNE:
  12.                 switch (c) {
  13.                     case ' ':
  14.                     case '\t':
  15.                         break;
  16.                     default
  17.                         putchar(c);
  18.                         etat = ETAT_NORMAL;
  19.                         break;
  20.                 }
  21.                 break;
  22.             case ETAT_NORMAL:
  23.                 switch (c) {
  24.                     case '\n':
  25.                         putchar('\n');
  26.                         etat=ETAT_DBT_LIGNE;
  27.                         break;
  28.                     default
  29.                         putchar(c);
  30.                         break;
  31.                 }
  32.         }
  33.     }
  34.     exit(EXIT_SUCCESS);
  35. }


Message édité par Chronoklazm le 24-02-2005 à 23:22:25

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
n°993203
pains-aux-​raisins
Fatal error
Posté le 25-02-2005 à 08:13:19  profilanswer
 

disons que c'est un début :D

n°993213
chrisbk
-
Posté le 25-02-2005 à 08:42:18  profilanswer
 

Chronoklazm a écrit :

Bon, je te sens chaud pour m'aider là, non ? :)


 
heuh nan, les parseurs fait main ca ressemble souvent a du spaghetti ou meme l'aventurier le plus intrepide n'ose s'aventurer [:petrus75]


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Probleme d'analyse lexicale

 

Sujets relatifs
[JS] Probleme de neuneuProbleme c++ et appli windows
Problème sur le modèle conceptuel d'un lycée. Identifiant "double".Problème d'affichage en PERL sous UNIX
probleme allocation memoire[OpenGL] problème d'éclairage
probleme num de telprobleme de cryptage d'une variable...
Problème sémaphore sous SolarisProblème compilation sur Linux
Plus de sujets relatifs à : Probleme d'analyse lexicale


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR