analyseur lexical en C

analyseur lexical en C - C - Programmation

Marsh Posté le 13-04-2012 à 16:48:48    

salut
je suis chargée de faire un analyseur lexical développé en langage C, j'arrive pas à faire un plan pour mon travail, les principaux structures que je dois créer. j'ai compris qu'il faut que je crée une structure de donnée qui contient deux champs:  

Code :
  1. struct res_retour
  2.     {
  3.         char unité;
  4.         char attribut;
  5.     }


Cependant y'en a pleins de questions qui se posent:  
comment ferai-je la vérification, quelle est la variable qui contiendra les mots clés? doit-elle etre une structure de donnée? si oui quelles sont les champs? ou doit-elle etre une pile, tableau?  et puis lors de traitement des différents cas {switch () case(nb): {...} break;case(id):{} break;...case(mot-clé) case (espace) ou doit-je stockés le résultat du case?  
 
 
 
Il est demandé de:
*Construire un automate fini qui accepte l’ensemble suivant  
des mots (unités lexicales ou jetons, terminaux d’une grammaire) { :, id, :=, ;, nb, ,, nbr, +, *, entier, réel, (, ), espace }
Où id représente les identificateurs alphanumériques qui commencent par un caractère alphabétique (l(l+c)*), nb représente les nombres entiers c+ et nbr est nombre réel c+.c+
espace représente une séquence d’espaces blancs ou de tabulations.
*Etendre l’automate pour pouvoir retourner à l’état final deux valeurs. La première est l’unité trouvée selon l’état final atteint et la deuxième est un attribut supplémentaire.  
Si l’unité trouvée est un id qui n’est pas un mot clé alors la première valeur retournée est id et la deuxième est une entrée dans une table contenant les identificateurs.  
Si l’unité trouvée est un mot clé (sachant que les mots clés sont : début, fin, program, var, entier, réel (Il faut sauvegarder quelque part cette liste de mots), alors, les valeurs retournées sont le mot clé et 0.
Si l’unité est nb alors la deuxième valeur est la valeur de ce nombre. L’automate doit pouvoir sauter les espaces, les retours à la ligne et les tabulations.
 
 
Je doit créer une fonction :RangerId() et UnilexId();
 
La fonction RangerId() a accès au tampon où l’unité lexicale identificateur a été localisée. On examine la table des symboles et si on trouve le lexème avec l’identificateur mot clé, RangerId() rend 0. Si on trouve le lexème comme variable du programme, RangerId() rend un pointeur vers une entrée dans la table des symboles. Si on ne trouve pas le lexème dans la table des symboles, il y est placé en tant que variable et un pointeur vers cette nouvelle entrée est retourné.
La fonction UnilexId() recherche le lexème dans la table des symboles. Si le lexème est un mot clé, l’unité lexicale correspondante est retournée; autrement, l’unité lexicale id est retournée.  
 
Voilà tout me parait ambiguë, votre aide me sera très utile .  
Merci d'avance

Reply

Marsh Posté le 13-04-2012 à 16:48:48   

Reply

Marsh Posté le 13-04-2012 à 16:59:44    

et utiliser un outil adapté, comme lex (ou flex) ?


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 13-04-2012 à 17:21:10    

non je ne dois utiliser que le C.

Reply

Marsh Posté le 13-04-2012 à 18:19:18    

Citation :

Construire un automate fini qui accepte l’ensemble suivant


Dessine le, ton automate, c'est pas dur.  
une fois dessiné, tu peux assez facilement créer une table qui a pour lignes les états, pour colonne les symboles, et qui a pour valeur [e, s] l'état auquel fait passer le symbole s quand on est dans l'état e.
 
Et après, ça roule ou presque.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 13-04-2012 à 19:34:10    

En fait dans ton cas, c'est encore plus simple (ce que je t'ai mis correspondait plus à la phase de l'analyseur lexical):
 
Tu peux faire un truc style (je garantis rien sur la qualité de ce qui suit, c'est juste pour te donner une idée de l'approche à suivre).
 

Code :
  1. #define TOKEN_START 0
  2. #define TOKEN_ASSIGN 1
  3. ...
  4. #define TOKEN_END  ...
  5. #define TOKEN_ERROR  ...
  6. static int lexint;
  7. static float lexreal;
  8. static char *lexident[MAX_IDENT_SIZE];
  9. static int identnum;
  10. static char *lexkw[8] = { "début", "fin", "program", "var", "entier", "réel"}; // faudra faire gaffe aux accents
  11. unsigned short next_token(FILE *f) {
  12.   static char current = EOF;
  13.   static char buffer[MAX_IDENT_SIZE+1]; // choisir une taille assez grande pour contenir un ident un int ou un reel
  14.   unsigned short token;
  15.   int i = 0;
  16.   if (current ==  EOF) {current = fgetc(f);}
  17.   switch (current) {
  18.       case EOF: token = TOKEN_END;
  19.                      break;
  20.       case ':': current = fgetc(f);
  21.                  if (current == '=') {
  22.                      current = EOF;
  23.                      token = TOKEN_ASSIGN;
  24.                  }
  25.                  else {
  26.                      token = TOKEN_DDOT;
  27.                  }
  28.                  break;
  29.     case ' ':  token = TOKEN_SPACE;
  30.                 break;
  31.     case 'A': case 'B':
  32.     ...
  33.     case 'Y': case 'Z':
  34.     ...
  35.      case 'a': case 'b':
  36.     ...
  37.     case 'y': case 'z':   do {
  38.                               buffer[i++] = current;
  39.                               current = fgetc(f);
  40.                               } while (((current >= 'A' && current <= 'Z') || (current >= 'a' && current <= 'z')) && (i <  MAX_IDENT_SIZE));
  41.                               buffer[i] = 0;
  42.                               if (i == MAX_IDENT_SIZE) {
  43.                                 token = TOKEN_ERROR;
  44.                               }
  45.                               else {
  46.                                   current = EOF;
  47.                                  // faire d'abord une recherche dans la tables des mots clés et retourner un token spécifique si oui
  48.                                  addident(lexident, buffer); // ajouter l'identificateur à la table s'il n'y est pas, et positionner identnum
  49.                                  token = TOKEN_IDENT;
  50.                               }
  51.                break;
  52.     ...
  53.     default: token = TOKEN_ERROR;
  54.                 break;
  55.   }
  56.   return token;
  57. }


 
Et je suppose que tu as qque part un analyseur syntaxique comme indique dans mon post précédent qui va faire un

Code :
  1. f = fopen(...);
  2. e = STATE_START;
  3. do {
  4.     t = next_token(f);
  5.     e = nextstate[e, t];
  6.     switch(e) {
  7.     // actions a faire pour l'état e s'il y en a
  8.     } while (e != STATE_END);
  9. fclose(f);


 
 
A+,


Message édité par gilou le 13-04-2012 à 19:35:17

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed