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