TP n°5 de Compilation

(Yacc AVEC Lex)

Exercice 1

1.1.
Ecrire ces deux codes dans les fichiers indiqués.
fichier-lex tp5exc1.lex
%{
#include "y.tab.h"
%}
%%
^\n    {return(terminer);}
\n     {return(finligne);}
[aA]   {return(lettreA);}
[bB]   {return(lettreB);}
.      {return(autre);}
fichier-yacc tp5exc1.yac
%{
int c;
%}
%token terminer finligne
%token lettreA lettreB
%token autre
%%
S : terminer         {return -1;}
  | M finligne       {return 0;}
  | error finligne   {return 1;}
  ;
M : lettreA M lettreB
  | M autre          {return (2);}
  |
  ;
%%
main() {
  do {
    c=yyparse();
    if (c==0) printf("mot accepté\n");
    if (c==1) printf("mot refusé\n");
    if (c==2) printf("erreur lexicale\n");
  } while(c>-1);
}
Puis réaliser cet analyseur :
lex tp5exc1.lex
yacc -d tp5exc1.yac
gcc lex.yy.c y.tab.c -ly -ll

1.2.
Modifier sur le même principe, c'est-à-dire en ajoutant un fichier-lex pour l'analyse lexicale, les analyseurs du TP4 correspondant à l'exercice 2 question 3, puis à l'exercice 3.

Exercice 2

Construire l'analyseur suivant.
  fichier-lex :
%{
#include "y.tab.h"
%}
%%
^\n    {return(terminer);}
\n     {return(finligne);}
[aA]   {return(lettreA);}
[bB]   {return(lettreB);}
[cC]   {return(lettreC);}
[dD]   {return(lettreD);}
.      {return(autre);}
fichier-yacc :
%{
int dollarbis;
%}
%token lettreA lettreB lettreC lettreD
%token terminer finligne autre
%%
D : terminer   {exit(-1);}
  | T finligne { if ($1==dollarbis) printf("égaux\n");
                 else printf("différents\n");
                 if (($1==0)&&(dollarbis==0)) printf("ça marche!\n");
                 dollarbis=0;
                 return 0; }
  ;
T : lettreA T  {$$=$2+1;}
  | lettreB T  {$$=$2-1;}
  | lettreC T  {dollarbis++; $$=$2;}
  | lettreD T  {dollarbis--; $$=$2;}
  | autre T    {$$=$2;}
  |            {dollarbis=0; $$=0;}
  ;
%%
main() {
  dollarbis=0;
  while (yyparse()==0);
}

2.1.
Que vérifient les tests ($1==dollarbis) et ($1==0) ? L'analyseur est-il robuste ?

2.2.
Modifier l'analyseur pour qu'il accepte le langage sur l'alphabet {N,S,E,W} ayant autant de N que de S et autant de E que W.

Exercice 3

Créer un analyseur lexico-syntaxique convivial et robuste pour chacun des langages suivants.

3.1.
Le langage bien parenthésé sur l'alphabet {0,1,+,*,(,)} accepté par la grammaire :
S → E+E|E*E
E → 0|1|(S)

3.2.
Le langage obtenu en remplaçant, dans le langage ci-dessus, 0 et 1 par des nombres entiers naturels d'au plus six chiffres.

3.3.
Le langage anbncn.

3.4.
L'ensemble des palindromes sur l'alphabet {a,b,x}ayant exactement une fois x.

3.5.
L'ensemble des palindromes sur l'alphabet {a,...,z} ayant exactement une fois x, avec la condition supplémentaire que l'analyseur ne devra pas définir plus de cinq tokens.

3.6.
Que faudrait-il rajouter à l'analyseur du deuxième langage de cet exercice pour qu'il retourne le résultat de l'opération correspondante ?
N.B. ne pas oublier les associativités et les conventions de priorité d'opérateur.