TP de compilation : une solution de l'exercice 2 du TP 5

2.1.
La variable héritée $$ mesure la différence  |a|-|b|. La variable dollarbis mesure la différence  |c|-|d|.
Par conséquent le test (dollarbis==$1) vérifie si l'excés/défaut de a par rapport à b est identique à celui de c par rapport à d.

Le test ($1==0) vérifie s'il y a autant de a que de b et le test (dollarbis==0) vérifie s'il y a autant de c que de d.
Si les deux test sont vrais, la ligne saisie contient autant de a que de b, et autant de c que d.

La robustesse de l'analyseur est due à :
• L'acceptation de n'importe quel caractère par le fichier-lex (grâce à sa dernière ligne), on a donc comme alphabet l'ensemble A du code ASCII étendu.
• Le fait que le fichier-yac est équivalent à un automate d'état fini acceptant tous les mots du langage A* (grâce à sa dernière ligne).

2.2.
fichier-lex:
%{
#include "y.tab.h"
%}
^\n return(terminer);  
\n  return(finligne);
N   return(nord);
S   return(sud);
E   return(est);
W   return(west);
.   return(autre);
fichier-yacc:
%{
int dollarbis;
int erreur;
%}
%token nord sud est west  
%token terminer finligne
%token autre
%%
D : terminer   {exit(-1);}
  | T finligne { if (erreur>0)
                    printf("erreur lexicale\n");
                else if (($1==0)&&(dollarbis==0))
                     printf("accepté\n");
                else printf("refusé\n");
                dollarbis=0; erreur=0;
                return 0; }
  ;
T : nord  T  {$$=$2+1;}
  | sud   T  {$$=$2-1;}
  | est   T  {dollarbis++;}
  | west  T  {dollarbis--;}
  | autre T  {$$=$2; erreur++;}
  |          {$$=0;}
  ;
%%
main()
{ erreur=0; dollarbis=0; while (yyparse()==0); }

N.B. : on a choisi ici de modifier le moins possible l'analyseur précédent. Les caractères autres que ceux de l'alphabet {N,S,E,W} donnent lieu à une erreur gérée au niveau syntaxique. Ce choix de reporter complètement les problèmes lexicaux au niveau syntaxique est bien évidemment contestable, mais il a le mérite ici de conserver à bon compte la robustesse de l'analyseur.

© 2000, 2017 – A. Sigayret